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

相关推荐
Word码3 小时前
[C++语法] 继承 (用法详解)
java·jvm·c++
TT哇3 小时前
【实习 】银行经理端两个核心功能的开发与修复(银行经理绑定逻辑修复和线下领取扫码功能开发)
java·vue.js
逝水如流年轻往返染尘3 小时前
Java中的数组
java
java1234_小锋4 小时前
Java高频面试题:BIO、NIO、AIO有什么区别?
java·面试·nio
用户8307196840824 小时前
Java IO三大模型(BIO/NIO/AIO)超详细总结
java
sheji34164 小时前
【开题答辩全过程】以 基于SSM的花店销售管理系统为例,包含答辩的问题和答案
java
Mr_sun.4 小时前
Day09——入退管理-入住-2
android·java·开发语言
MAGICIAN...4 小时前
【java-软件设计原则】
java·开发语言
JH30734 小时前
为什么switch不支持long
java