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

相关推荐
GlobalInfo3 小时前
2026年机器人多指灵巧手市场分析报告——涵盖行业调查、趋势分析与发展前景
大数据·人工智能·microsoft·微服务·机器人
学长毕设4 小时前
基于SpringBoot的实验室资产管理系统
java·spring boot·后端
zzu123zsw5 小时前
从臃肿的模板调用到声明式契约:深入 UniHttp 动态代理与多渠道生命周期扩展
java·spring boot·microsoft·unihttp
源码集结号6 小时前
云诊所门诊系统源码,基于SpringBoot+Vue.js架构,支持多租户设计与Docker容器化部署
java·spring boot·源码·医院信息系统·门诊系统·诊所系统
论文复现现场6 小时前
WRF、FEA 能用 L40S 加速吗?求解器检查、断点恢复与长期运行
java·数据库·算法·wrf·有限元分析·gpu计算·断点续算
啃瓜子的松鼠6 小时前
泛微OAe9-后端二开异步调用
java
秋天的怀念_David7 小时前
第二十一夜 · 数字黑洞与西西弗斯的惩罚
java·程序人生·算法
外收内放7 小时前
Python基础语法练习题(73)
java·前端·python
Wang's Blog7 小时前
Java 项目实战: 交友项目 - 环信后台发送消息测试
java·交友
用户3721574261358 小时前
Java 操作 Word 脚注和尾注:添加、读取与删除
java