1.微服务拆分远程调用

当一个服务需要调用另一个服务的数据时,我们不能直接拿到另一个服务数据,只能模拟前端,向另一个服务发送http的请求获取数据。
所以我们需要借助一个Spring为我们提供一个RestTemplate工具,可以方便的实现http请求的发送。使用步骤:
使用步骤

启动类

@MapperScan("com.hmall.cart.mapper")
@SpringBootApplication
public class CartApplication {
    public static void main(String[] args) {
        SpringApplication.run(CartApplication.class, args);
    }

    //spring的启动类同时也是一个配置类,我们可以配置RestTemplate
    @Bean
    public RestTemplate restTemplate() {
        return new RestTemplate();
    }

}
   private final RestTemplate restTemplate;
  
   private void handleCartItems(List<CartVO> vos) {

        // 1.获取商品id
        Set<Long> itemIds = vos.stream().map(CartVO::getItemId).collect(Collectors.toSet());
        // 2.查询商品
//        List<ItemDTO> items = itemService.queryItemByIds(itemIds);
        //2.1 使用restTemplate获取http响应
        ResponseEntity<List<ItemDTO>> response = restTemplate.exchange(
                "http://localhost:8081/items?ids={ids}",
                HttpMethod.GET,
                null,
                new ParameterizedTypeReference<List<ItemDTO>>() {
                },
                Map.of("ids", CollUtil.join(itemIds, ","))

        );
        //2.2解析响应
        if (!response.getStatusCode().is2xxSuccessful()){
            throw new BizIllegalException("查询商品信息异常");
        }
        List<ItemDTO> items = response.getBody();
        if (CollUtils.isEmpty(items)) {
            return;
        }
        // 3.转为 id 到 item的map
        Map<Long, ItemDTO> itemMap = items.stream().collect(Collectors.toMap(ItemDTO::getId, Function.identity()));
        // 4.写入vo
        for (CartVO v : vos) {
            ItemDTO item = itemMap.get(v.getItemId());
            if (item == null) {
                continue;
            }
            v.setNewPrice(item.getPrice());
            v.setStatus(item.getStatus());
            v.setStock(item.getStock());
        }
    }

2.服务治理(注册中心)

如果有多台机器部署item-service,我们写的代码只能访问端口8081,不能实现负载均衡,而且如果这个端口挂了,跟着cart-service也不能使用这个功能,这就是RestTemplate存在的问题
存在问题

2.1注册中心的原理

注册中心原理

2.2 nacos注册中心

目前开源的注册中心框架有很多,国内比较常见的有:

  • Eureka:Netflix公司出品,目前被集成在SpringCloud当中,一般用于Java应用
  • Nacos:Alibaba公司出品,目前被集成在SpringCloudAlibaba中,一般用于Java应用
  • Consul:HashiCorp公司出品,目前集成在SpringCloud中,不限制微服务语言

以上几种注册中心都遵循SpringCloud中的API规范,因此在业务开发使用上没有太大差异。由于Nacos是国内产品,中文文档比较丰富,而且同时具备配置管理功能(后面会学习),因此在国内使用较多,所以选择nacos。

2.3服务注册

1.在item-service的pom.xml中添加依赖:

        <!--nacos 服务注册发现-->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        </dependency>

2.配置Nacos
在item-service的application.yml中添加nacos地址配置:

spring:
  application:
    name: item-service # 服务名称
  cloud:
    nacos:
      server-addr: 192.168.150.101:8848 # nacos地址

2.4服务发现

1.在cart-service的pom.xml中添加依赖:

        <!--nacos 服务注册发现-->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        </dependency>

2.配置Nacos
在cart-service的application.yml中添加nacos地址配置:

spring:
  application:
    name: cart-service # 服务名称
  cloud:
    nacos:
      server-addr: 192.168.150.101:8848 # nacos地址

3.服务发现

    	private final DiscoveryClient  discoveryClient;

// 2.查询商品
//        List<ItemDTO> items = itemService.queryItemByIds(itemIds);
        //2.1根据服务名称获取服务的实列列表
        List<ServiceInstance> instances = discoveryClient.getInstances("item-service");
        if (CollUtils.isEmpty(instances)){
            return;
        }
        ServiceInstance serviceInstance = instances.get(RandomUtil.randomInt(instances.size()));
        //2.3 使用restTemplate获取http响应
        ResponseEntity<List<ItemDTO>> response = restTemplate.exchange(
                serviceInstance.getUri() +"/items?ids={ids}",
                HttpMethod.GET,
                null,
                new ParameterizedTypeReference<List<ItemDTO>>() {
                },
                Map.of("ids", CollUtil.join(itemIds, ","))

        );

3.openfeign

3.1openfeign初步认识

上述代码,为了获取服务数据需要写大量代码,所以就出现了利用openfeign。
openfeign是一个声明式的http客户端,其作用是基于mvc注解,帮助我们优雅的发送http请求。
1.引入依赖

  <!--openFeign-->
  <dependency>
      <groupId>org.springframework.cloud</groupId>
      <artifactId>spring-cloud-starter-openfeign</artifactId>
  </dependency>
  <!--负载均衡器-->
  <dependency>
      <groupId>org.springframework.cloud</groupId>
      <artifactId>spring-cloud-starter-loadbalancer</artifactId>
  </dependency>

2.启用OpenFeign
@EnableFeignClients,如果不在本包下,记得指定包
指定扫描

@EnableFeignClients
@MapperScan("com.hmall.cart.mapper")
@SpringBootApplication
public class CartApplication {
    public static void main(String[] args) {
        SpringApplication.run(CartApplication.class, args);
    }

    //spring的启动类同时也是一个配置类,我们可以配置RestTemplate
    @Bean
    public RestTemplate restTemplate() {
        return new RestTemplate();
    }

}

3.创建客户端
客户端
4.修改代码

//    private final RestTemplate restTemplate;
//    private final DiscoveryClient  discoveryClient;

    private final ItemClient itemClient;
     List<ItemDTO> items = itemClient.queryItemByIds(itemIds);`

3.2openfegin连接池

连接池
1.引入依赖
引入依赖

2.开启连接池功能
开启连接池功能

3.3日志

日志级别
如何定制日志级别
定制日志j级别

更多推荐