微服务通信

一、Feign远程调⽤

以前我们是通过RestTemplate发起远程调用的:

java 复制代码
//通过restTemplate调用商品微服务
String url = "service-product";
Product product = restTemplate.getForObject( "http://"+url+"/product/" + pid, Product.class);

但是这个方法存在一些问题:

①代码可读性差

②参数复杂,url难以维护

所以我们在这篇文章中引入了两个新的通信服务:Feign和Dubbo

1.1 Feign简介

Feign是Spring Cloud提供的⼀个声明式的伪Http客户端, 它使得调⽤远程服务就像调⽤本 地服务⼀样简单, 只需要创建⼀个接⼝并添加⼀个注解即可。 Nacos很好的兼容了Feign, Feign 默认集了Ribbon, 所以在Nacos下使⽤Fegin默认就实现了负载均衡的效果 官⽅地址: https://github.com/OpenFeign/feign

1.2 基本使⽤

//1.加入Feign的依赖(pom.xml文件)

XML 复制代码
<!--fegin组件--> 
<dependency> 
 <groupId>org.springframework.cloud</groupId> 
 <artifactId>spring-cloud-starter-openfeign</artifactId> 
</dependency>

//2. 在主类上添加Fegin的注解

java 复制代码
@SpringBootApplication
@EnableFeignClients //开启Fegin
public class ShopOrderApplication {
    public static void main(String[] args) {
        SpringApplication.run(ShopOrderApplication.class, args);
    }
    
}

//3.创建一个 service, 并使⽤Fegin实现微服务调⽤

java 复制代码
@FeignClient("service-product")//声明调⽤的提供者的name
public interface IProductService {
    @GetMapping(value = "/product/{pid}")
    Product findByPid(@PathVariable("pid") Integer pid);
}

//4. 修改controller代码(通过feign来进行微服务的调用),并启动验证

java 复制代码
@RestController
public class OrderController {
    @Autowired
    private IProductService productService;
    @Autowired
    private IOrderService orderService;
    //获取nacos中服务的元数据
    @Autowired
    private DiscoveryClient discoveryClient;
    //Ribbon下单
    @RequestMapping("/order/prod/{pid}")
    public Order order(@PathVariable("pid") Integer pid) {
        //通过fegin调用商品微服务
        Product product = productService.findByPid(pid);
        //下单(创建订单)
        Order order = new Order();
        order.setUid(1);
        order.setUsername("测试用户");
        order.setPid(pid);
        order.setPname(product.getPname());
        order.setPprice(product.getPprice());
        order.setNumber(1);
        orderService.createOrder(order);
        return order;
    }
}

//5. 重启order微服务,查看效果

1.3 ⾃定义配置

Feign可以⽀持很多的⾃定义配置,如下表所示:

|---------------------|----------|---------------------------------------|
| 类型 | 作⽤ | 说明 |
| feign.Logger.Level | 修改⽇志级别 | 包含四种不同的级别: NONE、 BASIC、 HEADERS、 FULL |
| feign.codec.Decoder | 响应结果的解析器 | http远程调⽤的结果做解析,例 如解析json字符串为java对象 |
| feign.codec.Encoder | 请求参数编码 | 将请求参数编码,便于通过http 请求发送 |
| feign. Contract | ⽀持的注解格式 | 默认是SpringMVC的注解 |
| feign. Retryer | 失败重试机制 | 请求失败的重试机制,默认是没 有,不过会使⽤ Ribbon的重试 |

⼀般情况下,默认值就能满⾜我们使⽤,如果要⾃定义时,只需要创建⾃定义的@Bean覆盖默认Bean 即可。

配置⽂件⽅式

基于配置⽂件修改feign的⽇志级别可以针对单个服务:

java 复制代码
feign: 
 client:
 config: 
 service-product: # 针对某个微服务的配置
 loggerLevel: FULL # ⽇志级别 

也可以针对所有服务:

java 复制代码
feign: 
 client:
 config: 
 default: # 这⾥⽤default就是全局配置,如果是写服务名称,则是针对某个微服务的配
置
 loggerLevel: FULL # ⽇志级别

⽽⽇志的级别分为四种:

NONE:不记录任何⽇志信息,这是默认值

BASIC:仅记录请求的⽅法, URL以及响应状态码和执⾏时间

HEADERS:在BASIC的基础上,额外记录了请求和响应的头信息

FULL:记录所有请求和响应的明细,包括头信息、请求体、元数据。

二、Dubbo

2.1 基本简介

Dubbo是阿⾥巴巴开源的基于 Java 的⾼性能 RPC分布式服务框架,致⼒于提供⾼性能和透明化 的RPC远程服务调⽤⽅案,以及SOA服务治理⽅案。 Spring Cloud Alibaba微服务开发框架集成 了Dubbo,可实现微服务对外暴露Dubbo协议的接⼝,Dubbo协议相⽐RESTful协议速度更快 RPC:RPC是远程过程(Remote Procedure Call)的缩写形式,调⽤RPC远程⽅法就像调⽤本地 ⽅法⼀样,Dubbo之前阿⾥研发,中间停⽌维护2年,最后开启维护并捐献给Apache dubbo官⽹: http://dubbo.io/

2.2 基础实现

A.提供统⼀业务api (shop_common)

java 复制代码
package com.apesource.shop_common.service;

import com.apesource.shop_common.domain.Product;

public interface IProductService {
    /**
     实战中,会将所有服务接口设计给一个叫做api的服务,单独维护,此处就在common服务设置
     */
    Product findByPid(Integer pid);

B.编辑服务提供者product

//1.添加依赖

XML 复制代码
<!-- dubbo -->
<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-dubbo</artifactId>
</dependency>

//2.添加dubbo配置

java 复制代码
dubbo:
  scan:
    base-packages: com.apesource.shop_product.service.impl
  protocols:
    dubbo:
      name: dubbo
      port: -1
  registry:
    address: spring-cloud://localhost

//3.编写并暴露服务

java 复制代码
import com.apesource.shop_common.domain.Product;
import com.apesource.shop_common.service.IProductService;
import com.apesource.shop_product.dao.ProductMapper;
import org.apache.dubbo.config.annotation.Service;
import org.springframework.beans.factory.annotation.Autowired;

//暴露服务:注意这⾥使⽤的是dubbo提供的注解@Service,⽽不是Spring的
@Service
public class ProductServiceImpl implements IProductService {
    @Autowired
    ProductMapper productMapper;

    @Override
    public Product findByPid(Integer pid) {
        return productMapper.selectById(pid);
    }
}

C.编辑服务消费者

//1.添加依赖

XML 复制代码
<!--dubbo--> 
<dependency> 
 <groupId>com.alibaba.cloud</groupId> 
 <artifactId>spring-cloud-starter-dubbo</artifactId> 
</dependency>

//2.添加dubbo配置

XML 复制代码
dubbo:
  registry:
    address: spring-cloud://localhost
  cloud:
    subscribed-services: service-product

//3.引⽤服务

java 复制代码
@RestController
public class OrderController {

    //引用服务
    @Reference
    IProductService productService;
    @Autowired
    private IOrderService orderService;
    //Ribbon下单
    @RequestMapping("/order/prod/{pid}")
    public Order order(@PathVariable("pid") Integer pid) {
        //通过dubbo调用商品微服务
        Product product = productService.findByPid(pid);
        //下单(创建订单)
        Order order = new Order();
        order.setUid(1);
        order.setUsername("测试用户");
        order.setPid(pid);
        order.setPname(product.getPname());
        order.setPprice(product.getPprice());
        order.setNumber(1);
        orderService.createOrder(order);
        return order;
    }
}

//4.重启服务类

相关推荐
m0_5719575843 分钟前
Java | Leetcode Java题解之第543题二叉树的直径
java·leetcode·题解
魔道不误砍柴功3 小时前
Java 中如何巧妙应用 Function 让方法复用性更强
java·开发语言·python
NiNg_1_2343 小时前
SpringBoot整合SpringSecurity实现密码加密解密、登录认证退出功能
java·spring boot·后端
闲晨3 小时前
C++ 继承:代码传承的魔法棒,开启奇幻编程之旅
java·c语言·开发语言·c++·经验分享
种树人202408193 小时前
如何在 Spring Boot 中启用定时任务
spring boot
Chrikk4 小时前
Go-性能调优实战案例
开发语言·后端·golang
幼儿园老大*4 小时前
Go的环境搭建以及GoLand安装教程
开发语言·经验分享·后端·golang·go
canyuemanyue4 小时前
go语言连续监控事件并回调处理
开发语言·后端·golang
杜杜的man4 小时前
【go从零单排】go语言中的指针
开发语言·后端·golang
测开小菜鸟4 小时前
使用python向钉钉群聊发送消息
java·python·钉钉