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

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

方案一:

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

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);
        }
}
相关推荐
荒川之神1 小时前
拉链表概念与基本设计
java·开发语言·数据库
cch89181 小时前
汇编与Go:底层到高层的编程差异
java·汇编·golang
chushiyunen1 小时前
python中的@Property和@Setter
java·开发语言·python
禾小西1 小时前
Java中使用正则表达式核心解析
java·python·正则表达式
yoyo_zzm1 小时前
JAVA (Springboot) i18n国际化语言配置
java·spring boot·python
APIshop1 小时前
Java获取京东商品详情接口(item_get)实战指南
java·linux·数据库
Mr.Entropy1 小时前
springboot2.x集成Flyway
java
disgare1 小时前
关于 spring 工程中添加 traceID 实践
java·后端·spring
李白的粉1 小时前
基于springboot+vue的旅游民宿管理系统
java·spring boot·vue·毕业设计·课程设计·源代码·旅游民宿管理系统
摇滚侠2 小时前
搭建前端开发环境 安装 nodejs 设置淘宝镜像 最简化最标准版本 不使用 NVM NVM 高版本无法安装低版本 nodejs
java·开发语言·node.js