目录
在微服务架构中,通常存在多个服务之间的远程调用的需求。远程调用通常包含两个部分:序列化和通信协议。常见的序列化协议包括json、xml、 hession、 protobuf、thrift、text、 bytes等,目前主流的远程调用技术有基于HTTP的RESTful接口以及基于TCP的RPC协议。
两种通信方式的区别
RESTful | RPC | |
通讯协议 | HTTP协议 | TCP协议 |
数据格式 | 通常使用JSON或XML等常见的数据格式来表示请求和响应的数据 | 可以使用自定义的数据格式 |
接口风格 | 遵循REST的设计原则,使用URL来描述资源,并使用HTTP方法对资源进行操作 | 通常使用类似于函数调用的方式进行通信,通过调用远程方法来实现服务调用 |
可读性 | 具有较好的可读性 | 可读性较差 |
性能 | 基于TCP的RPC协议通常比基于HTTP的RESTful接口具有更高的性能,因为它可以直接操作底层的TCP连接,减少了HTTP协议的开销 | |
功能扩展 | 功能扩展性较弱 | 支持更多的功能扩展,例如支持事务、流式传输等 |
应用 | 微服务架构 | SOA架构 |
基于HTTP协议的RESTful接口的实现
RestTemplate
RestTemplate是Spring Framework提供的用于发送HTTP请求的客户端工具。它封装了很多简化和便捷化的功能,使得在Java应用中进行HTTP通信变得更加方便。RestTemplate可以发送各种类型的HTTP请求,例如GET、POST、PUT、DELETE等,同时也支持异步请求和文件上传。它提供了一系列方法来发送请求,并返回响应的结果。
在微服务架构中,RestTemplate通常用于服务间的通信。通过发送HTTP请求,微服务可以发送请求并获取其他服务的响应结果,实现服务之间的数据交互和调用。
RestTemplate的基本使用流程:
-
创建RestTemplate对象:首先,需要创建一个RestTemplate对象,可以通过以下方式创建:
RestTemplate restTemplate = new RestTemplate();
-
发送HTTP请求:使用RestTemplate发送HTTP请求,可以使用该对象的各种方法,如getForObject()、postForObject()等。根据需要选择适当的HTTP方法和请求参数。
例如,发送GET请求并获取返回值:
String url = "http://api.example.com/getData"; String response = restTemplate.getForObject(url, String.class);
发送POST请求并传递请求体:
String url = "http://api.example.com/createData"; SomeObject requestData = new SomeObject(...); // 创建请求对象 SomeObject response = restTemplate.postForObject(url, requestData, SomeObject.class);
-
处理响应:根据请求的返回值类型选择相应的方法来处理响应。对于上述示例中的GET请求,返回的是一个String类型的响应,可以将其直接使用。对于POST请求,可以将返回的响应转换为对应的对象类型。
-
错误处理:在使用RestTemplate时,还应该考虑处理请求过程中可能出现的异常和错误情况。通常可以使用try-catch块来捕获异常,并根据需要进行相应的处理。
Feign
Feign是Spring Cloud提供的一个声明式的伪Http客户端, 它使得调用远程服务就像调用本地服务一样简单, 只需要创建一个接口并添加一个注解即可。Feign在底层使用了Ribbon来实现负载均衡,并整合了Netflix Eureka实现服务发现。它还支持请求和响应的日志记录,方便调试和追踪。
- 首先,添加坐标。
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
- 并且在主类添加上@EnableFeignClients的注解。
@EnableFeignClients注解告诉框架扫描所有使用注解@FeignClient定义的feign客户端,并把feign客户端注册到IOC容器中(@EnableFeignClients导入了FeignClientsRegistrar类,FeignClientsRegistrar实现了ImportBeanDefinitionRegistrar,负责进行Feign的注入)。
- 创建一个service, 并使用Fegin实现微服务调用
@FeignClient("name")//声明调用的提供者的name
public interface IService {
//指定调用提供者的哪个方法
//@FeignClient+@GetMapping 就是一个完整的请求路径
@GetMapping(value = "/路径")
Product methodName(Integer id); // 需要调用的方法
}
- 修改controller代码,并启动验证
除了上述必要步骤外,Feign还可以进行一些配置,比如配置日志以及一些使用优化。
Dubbo
Dubbo是阿里巴巴开源的高性能、轻量级的服务治理框架。它提供了完整的服务治理能力,包括服务注册与发现、负载均衡、容错、集群管理等。
Dubbo基于RPC(远程过程调用)实现服务间的通信。通过Dubbo,你可以将应用程序中的方法调用转换为跨网络的远程调用,并隐藏了底层通信细节。它还提供了丰富的配置选项和扩展点,可以用于构建高性能、稳定可靠的分布式系统。
Dubbo支持多种协议(如TCP、HTTP等)和序列化方式(如JSON、Hessian等),提供了灵活的配置选项和高度可扩展的架构。它有助于构建分布式架构中的服务提供者和消费者,并提供了对服务调用的监控和管理。
Dubbo的基本使用流程:
- 导入依赖
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-dubbo</artifactId>
</dependency>
- 提供统一的API
Dubbo的使用更像是方法的调用,在使用时,将公共的API存放在公共位置等待使用,具体过程如下:
首先,为所有服务提供者和消费者共享的接口定义一个独立的模块,称为接口模块。接口模块中只包含接口的定义,不包含具体的实现。在服务提供者模块中,实现接口模块中所定义的接口,并将其注册到Dubbo的服务注册中心。服务提供者模块中也包含服务的配置信息,如版本号、超时时间等。在服务消费者模块中,同样引入接口模块,并在需要调用服务的地方使用接口进行编程。通过Dubbo的服务发现功能,可以从服务注册中心获取到服务提供者的地址信息,并发起远程调用。
/**
实战中,会将所有服务接口设计给一个叫做api的服务,单独维护,此处就在common服务设置
*/
public interface IService {
void method(Integer id);
}
- 配置yaml文件
dubbo:
application:
name: dubbo-provider
registry:
address: spring-cloud://localhost # 注册中心
scan:
base-packages: com.apesource.service.impl # 开启包扫描
protocols:
dubbo:
name: dubbo # 服务协议
port: -1 # 服务端口 使用随机端口
provider:
timeout: 5000
application:指定应用程序的名称。
registry:指定注册中心的配置信息。
protocol:指定协议的配置信息。
provider:指定提供者的配置信息。
- 编写并暴露服务,即调用统一API
对于服务提供者,可以使用@Service注解来标记服务实现类,将其暴露为Dubbo服务。需要注意的是,此处的@Service注解不是Spring中的注解,而是由Dubbo提供的。
@Service
public class UserServiceImpl implements UserService {
// 实现UserService接口的具体方法
}
对于服务消费者,可以使用@Reference注解来标记对Dubbo服务的引用。
@Service
public class UserServiceConsumer {
@Reference
private UserService userService;
// 调用userService中的方法
}
以上就是常用的几种微服务的通信方式,当然还有别的技术可以实现,本文仅供参考。