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注册中心是这么做的。

相关推荐
大阿明4 小时前
Spring Boot(快速上手)
java·spring boot·后端
bearpping4 小时前
Java进阶,时间与日期,包装类,正则表达式
java
邵奈一4 小时前
清明纪念·时光信笺——项目运行指南
java·实战·项目
sunwenjian8865 小时前
Java进阶——IO 流
java·开发语言·python
sinat_255487815 小时前
读者、作家 Java集合学习笔记
java·笔记·学习
皮皮林5515 小时前
如何画出一张优秀的架构图?(老鸟必备)
java
百锦再5 小时前
Java 并发编程进阶,从线程池、锁、AQS 到并发容器与性能调优全解析
java·开发语言·jvm·spring·kafka·tomcat·maven
森林猿5 小时前
java-modbus-读取-modbus4j
java·网络·python
tobias.b5 小时前
计算机基础知识-数据结构
java·数据结构·考研
reembarkation6 小时前
光标在a-select,鼠标已经移出,下拉框跟随页面滚动
java·数据库·sql