SpringCloud从入门到上天:Nacos做微服务注册中心(二)

一:远程调用基本流程

1:基本流程

2:模拟一个真实场景

二:编写测试代码进行RPC

1:编写订单编码

复制代码
@RestController
public class OrderController {

    @Autowired
    private OrderService orderService;

    @GetMapping("/create")
    public Order createOrder(@RequestParam("userId") Long userId, @RequestParam("productId") Long productId) throws NacosException {
        Order order = orderService.createOrder(productId, userId);
        return order;
    }
}


@Service
public class OrderServiceImpl implements OrderService{

    @Autowired
    NacosServiceDiscovery nacosServiceDiscovery;
    @Autowired
    RestTemplate restTemplate;

    @Override
    public Order createOrder(Long productId, Long user) throws NacosException {
        Order order = new Order();
        order.setId(productId);
        order.setProducts(List.of(productId));
        return order;
    }

    private Product getProduct(Long productId) throws NacosException {
        List<ServiceInstance> instances = nacosServiceDiscovery.getInstances("service-product");
        ServiceInstance serviceInstance = instances.get(0);
        String url = "http://"+serviceInstance.getHost()+":"+serviceInstance.getPort()+"/product/"+productId;
        Product product = restTemplate.getForObject(url, Product.class);
        return product;
    }
}

2:编写商品编码

复制代码
@RestController
public class ProductController {


    @Autowired
    ProductService productService;

    @GetMapping("/product/{id}")
    public Product getProductbyId(@PathVariable("id") Long productId){
        return  productService.getProductById(productId);
    }
}


@Service
public class productServiceImpl implements ProductService {
    @Override
    public Product getProductById(Long id) {
        Product product = new Product();
        product.setProductName("苹果");
        product.setId(id);
        return product;
    }
}

到这我们已经实现了基于注册中心的远程调用:http版本的。

3:负载均衡

复制代码
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-loadbalancer</artifactId>
        </dependency>

@SpringBootTest
public class LoadBalanceTest {

    @Autowired
    LoadBalancerClient loadBalancerClient;

    @Test
    void test(){
        for (int i = 0; i < 100; i++) {
            ServiceInstance choose = loadBalancerClient.choose("service-product");
            System.out.println("choose"+choose.getHost()+":"+choose.getPort());
        }
    }
}

choose192.168.59.1:8002
choose192.168.59.1:8001
choose192.168.59.1:8002
choose192.168.59.1:8001
choose192.168.59.1:8002
choose192.168.59.1:8001
choose192.168.59.1:8002
choose192.168.59.1:8001
choose192.168.59.1:8002
choose192.168.59.1:8001
choose192.168.59.1:8002
choose192.168.59.1:8001
choose192.168.59.1:8002
choose192.168.59.1:8001
choose192.168.59.1:8002
choose192.168.59.1:8001
choose192.168.59.1:8002
choose192.168.59.1:8001
choose192.168.59.1:8002
choose192.168.59.1:8001
choose192.168.59.1:8002
choose192.168.59.1:8001
choose192.168.59.1:8002
choose192.168.59.1:8001
choose192.168.59.1:8002
choose192.168.59.1:8001
choose192.168.59.1:8002
choose192.168.59.1:8001
choose192.168.59.1:8002
choose192.168.59.1:8001
choose192.168.59.1:8002
choose192.168.59.1:8001
choose192.168.59.1:8002
choose192.168.59.1:8001
choose192.168.59.1:8002
choose192.168.59.1:8001
choose192.168.59.1:8002
choose192.168.59.1:8001
choose192.168.59.1:8002
choose192.168.59.1:8001
choose192.168.59.1:8002
choose192.168.59.1:8001
choose192.168.59.1:8002
choose192.168.59.1:8001
choose192.168.59.1:8002
choose192.168.59.1:8001
choose192.168.59.1:8002
choose192.168.59.1:8001
choose192.168.59.1:8002
choose192.168.59.1:8001
choose192.168.59.1:8002
choose192.168.59.1:8001
choose192.168.59.1:8002
choose192.168.59.1:8001
choose192.168.59.1:8002
choose192.168.59.1:8001
choose192.168.59.1:8002
choose192.168.59.1:8001
choose192.168.59.1:8002
choose192.168.59.1:8001
choose192.168.59.1:8002
choose192.168.59.1:8001
choose192.168.59.1:8002
choose192.168.59.1:8001
choose192.168.59.1:8002
choose192.168.59.1:8001
choose192.168.59.1:8002
choose192.168.59.1:8001
choose192.168.59.1:8002
choose192.168.59.1:8001
choose192.168.59.1:8002
choose192.168.59.1:8001
choose192.168.59.1:8002
choose192.168.59.1:8001
choose192.168.59.1:8002
choose192.168.59.1:8001
choose192.168.59.1:8002
choose192.168.59.1:8001
choose192.168.59.1:8002
choose192.168.59.1:8001
choose192.168.59.1:8002
choose192.168.59.1:8001
choose192.168.59.1:8002
choose192.168.59.1:8001
choose192.168.59.1:8002
choose192.168.59.1:8001
choose192.168.59.1:8002
choose192.168.59.1:8001
choose192.168.59.1:8002
choose192.168.59.1:8001
choose192.168.59.1:8002
choose192.168.59.1:8001
choose192.168.59.1:8002
choose192.168.59.1:8001
choose192.168.59.1:8002
choose192.168.59.1:8001
choose192.168.59.1:8002
choose192.168.59.1:8001
choose192.168.59.1:8002
choose192.168.59.1:8001

基于此,我们修改负载均衡的代码。

复制代码
@Service
public class OrderServiceImpl implements OrderService{

    @Autowired
    NacosServiceDiscovery nacosServiceDiscovery;
    @Autowired
    RestTemplate restTemplate;
    @Autowired
    LoadBalancerClient loadBalancerClient;

    @Override
    public Order createOrder(Long productId, Long user) throws NacosException {
        Order order = new Order();
        order.setId(productId);
        order.setProducts(List.of(productId));
        return order;
    }

    private Product getProduct(Long productId) throws NacosException {
        ServiceInstance serviceInstance = loadBalancerClient.choose("service-product");
        String url = "http://"+serviceInstance.getHost()+":"+serviceInstance.getPort()+"/product/"+productId;
        Product product = restTemplate.getForObject(url, Product.class);
        return product;
    }
}

4:@LoadBalance

这样的话,RestTemplate默认就带有了负载均衡功能。

url中真实的ip地址换成应用名称,RestTemplate可以动态给我们进行替换。

复制代码
@Configuration
public class ProductServiceConfig {


    @LoadBalanced
    @Bean
    public RestTemplate restTemplate(){
        return new RestTemplate();
    }
}

public class OrderServiceImpl implements OrderService{

    @Autowired
    NacosServiceDiscovery nacosServiceDiscovery;
    @Autowired
    RestTemplate restTemplate;
    @Autowired
    LoadBalancerClient loadBalancerClient;

    @Override
    public Order createOrder(Long productId, Long user) throws NacosException {
        Order order = new Order();
        order.setId(productId);
        order.setProducts(List.of(productId));
        return order;
    }

    private Product getProduct(Long productId) throws NacosException {
//        ServiceInstance serviceInstance = loadBalancerClient.choose("service-product");
        // 这里改为应用名称即可。
        String url = "http://service-product"+"/product/"+productId;
        Product product = restTemplate.getForObject(url, Product.class);
        return product;
    }
}

5:思考

如果注册中心宕机,远程过程调用还能成功吗?

应用服务中会进行实例缓存,将注册中心的数据进行同步和实时更新。当注册中心宕机了

1:如果调用过的接口:缓存中已经拿到过地址列表。可以通讯

2:如果没有调用过:缓存中没有,需要第一次进行,则必须去注册中心拿地址。

Nacos注册中心是这么做的。

相关推荐
AC赳赳老秦6 分钟前
CSDN 技术社区数据采集:OpenClaw 抓取公开技术热帖,生成领域技术热点周报
java·大数据·前端·数据库·python·php·openclaw
磁爆步兵27 分钟前
内存分区:程序运行的核心秘密
java·开发语言·jvm
流星白龙1 小时前
【Docker】4.NameSpace空间隔离实战
java·运维·docker
AI人工智能+电脑小能手1 小时前
【大白话说Java面试题 第207题】【09_Zookeeper篇】第8题:谈谈 ZooKeeper 的可靠性保障机制
java·zookeeper·高可用·可靠性·分布式系统
harmful_sheep1 小时前
maven多版本包导致java.lang.NoClassDefFoundError
java·maven
Mark_ZP2 小时前
【锁2】锁的分类与概念
java·
caishenzhibiao2 小时前
顺势捕猎者副图 同花顺期货通指标
java·c语言·c#
VortMall2 小时前
出海引流运维双升级|VortMall微服务商城系统v1.3.12 升级更新
运维·微服务·facebook
笨蛋不要掉眼泪2 小时前
RabbitMQ消息队列:SpringAMQP
java·分布式·rabbitmq
zzzll11112 小时前
Spring Cloud 微服务:从入门到实践
spring·spring cloud·微服务