微服务分模块后怎么跨模块访问资源

如果我们使用微服务框架后,每个模块变的相互独立,有自己的端口,那两个模块之间如何相互通信。

方案一:

使用糊涂工具向指定地址发送请求

java 复制代码
public void testGetByParam() {
    //可以单独传入http参数,这样参数会自动做URL编码,拼接在URL中
    HashMap<String, Object> paramMap = new HashMap<>();
    paramMap.put("pageNum", 1);
    paramMap.put("pageSize", 10);
    String result = HttpUtil.get("http://localhost:9995/nursing_project", paramMap);//直接发送get
    System.out.println(result);
}

方案二:

使用spring框架集成的RestTemplate

①注册bean

java 复制代码
@Configuration
public class RemoteCallConfig {
    @Bean
    @LoadBalanced
    public RestTemplate restTemplate() {
        return new RestTemplate();
    }
}

②直接注入使用

java 复制代码
import org.springframework.web.client.RestTemplate;
@Service
public class CartServiceImpl  {
    private final RestTemplate restTemplate;
    
    private void handleCartItems(List<CartVO> vos) {
        // 1.获取商品id
        Set<Long> itemIds = vos.stream().map(CartVO::getItemId).collect(Collectors.toSet());
        // 2.查询商品,因为已经划分了模块,itemService并不在此模块中,所以这种调用方式已经不行了
        //List<ItemDTO> items = itemService.queryItemByIds(itemIds);
        //处理一下字符串
        StringBuilder ids= new StringBuilder();
        for (Long itemId : itemIds) {
            ids.append(itemId).append(",");
        }
        //去掉最后一个逗号
        ids = new StringBuilder(ids.substring(0, ids.length() - 1));
        //使用RestTemplate发生请求并接收数据
        String forObject = restTemplate.getForObject("http://localhost:8081/items?ids=" + ids, String.class);
        //json字符串转集合
        List<ItemDTO> items = JSONUtil.toList(forObject, ItemDTO.class);
   }
}

方案三:

使用DiscoveryClient,因为我们在配置文件里给每个模块都起了名字,所以我们可以不用输很长的地址,直接使用模块名称访问

java 复制代码
spring:
  application:
    name: hm-cart
java 复制代码
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;

@Service
@RequiredArgsConstructor
public class CartServiceImpl{
    private final DiscoveryClient discoveryClient;
    
    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);
        //处理一下字符串
        String ids = itemIds.stream().map(String::valueOf).collect(Collectors.joining(","));
        //手动负载均衡
        List<ServiceInstance> instances = discoveryClient.getInstances("hm-item");//使用名称拿到所有的这个模块的实例
        ServiceInstance serviceInstance = instances.get(RandomUtil.randomInt(instances.size()));//随机挑一个端口
        // 获取服务的地址
        String url = serviceInstance.getUri().toString();
        String json = restTemplate.getForObject(url + "/items?ids=" + ids, String.class);
        List<ItemDTO> items = JSONUtil.toList(forObject, ItemDTO.class);
}

方案四(推荐):

使用OpenFeign创建相应模块的客户端与loadBalancer进行负载均衡默认为轮循

①引入依赖

XML 复制代码
 <!--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>
  <!--nacos 服务注册发现-->
<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>

②写客户端

java 复制代码
//加入容器
@FeignClient("hm-item")//模块名
public interface ItemClient {

    @GetMapping("/items")//请求接口
    List<ItemDTO> queryItemByIds(@RequestParam("ids") Collection<Long> ids);//与模块此接口的控制层的方法声明一样;
}

③启动类增加注解@EnableFeignClients

java 复制代码
@EnableFeignClients
@SpringBootApplication
@MapperScan("com.hmall.cart.mapper")
public class HmCartApplication {
    public static void main(String[] args) {
        SpringApplication.run(HmCartApplication.class, args);
    }
}

④注入使用

java 复制代码
@Service
@RequiredArgsConstructor
public class CartServiceImpl{
    private final ItemClient itemClient;
    private void handleCartItems(List<CartVO> vos) {
        // 1.获取商品id
        Set<Long> itemIds = vos.stream().map(CartVO::getItemId).collect(Collectors.toSet());
        //跨模块查询
        List<ItemDTO> items = itemClient.queryItemByIds(itemIds);
        }
}
相关推荐
captain37633 分钟前
MyBatis(入门5)其他查询操作
java·数据库·spring boot·mybatis
Novproxy_Z1 小时前
商用代理避坑:如何识别商家拿机房 IP 冒充住宅 IP
java·网络·tcp/ip
文丑颜不良啊2 小时前
LeetCode1481~1500题目解析
java·leetcode
2601_962885722 小时前
quotes 字段全解:涨跌幅、振幅、换手率的口径与单位
java·前端·spring
前端精髓2 小时前
调用openrouter的免费API模型
java·前端·javascript
步行cgn2 小时前
Spring MVC 拦截器 Interceptor 详解:从执行流程到实战应用
java·spring·mvc
文丑颜不良啊3 小时前
LeetCode1381~1400题目解析
java·leetcode
开开心心_Every3 小时前
快速隐藏程序工具自定义快捷键一键切换
java·开发语言·前端·spring·智能手机·word·intellij-idea
萧瑟余晖3 小时前
Spring Batch核心模型与快速上手详解
java·spring·batch
CodeGL4 小时前
开源的分布式任务调度平台:XXL-Job
分布式·开源