首页 如何调用本业务模块外的服务——服务调用
文章
取消

如何调用本业务模块外的服务——服务调用

服务调用方式

既然引入了注册中心来统一的管理服务的每个实例,那么我们就可以大方的去调用其他的服务了。

服务间调用常见的两种方式:RPC 与 HTTP:

  1. RPC 全称 Remote Produce Call 远程过程调用,速度快,效率高,早期的 WebService 接口,现在热门的 Dubbo、gRPC 、Thrift、Motan 等,都是 RPC 的典型代表
  2. HTTP 协议(HyperText Transfer Protocol,超文本传输协议)是因特网上应用最为广泛的一种网络传输协议,所有的 WWW 文件都必须遵守这个标准。对服务的提供者和调用方没有任何语言限定,更符合微服务语言无关的理念。时下热门的 RESTful 形式的开发方式,也是通过 HTTP 协议来实现的。

Spring Cloud 体系下常用的 HTTP 调用方式

  1. RestTemplate,是 Spring 提供的用于访问 Rest 服务的客户端,RestTemplate 提供了多种便捷访问远程 Http 服务的方法,能够大大提高客户端的编写效率。
  2. Ribbon,由 Netflix 出品,更为人熟知的作用是客户端的 Load Balance(负载均衡)。
  3. Feign,同样由 Netflix 出品,是一个更加方便的 HTTP 客户端,用起来就像调用本地方法,完全感觉不到是调用的远程方法。内部也使用了 Ribbon 来做负载均衡功能。

RestTemplate

当我们使用 Java 编写客户端发送 HTTP 请求时,通常需要使用一些辅助库。RestTemplate 是 Spring Framework 中用于简化 HTTP 请求的一个模块。它提供了对 GET、POST、PUT 和 DELETE 等 HTTP 请求方法的支持,同时支持 URI 模板、请求/响应拦截、错误处理等一系列功能。

使用 RestTemplate,我们可以以一种非常简单和直观的方式发送 HTTP 请求,如:

1
2
RestTemplate restTemplate = new RestTemplate();
String response = restTemplate.getForObject("http://example.com/api/resource", String.class);

这里我们创建了一个 RestTemplate 实例,然后使用其 getForObject() 方法发送了一个 GET 请求到指定的 URI。该方法返回了一个类型为 String 的响应体。通过 RestTemplate,我们无需手动处理 HTTP 连接、请求头、请求体等一系列细节,可以非常方便地发送 HTTP 请求并解析响应。

除了 getForObject() 方法,RestTemplate 还提供了一系列其他的请求方法,如 getForEntity()、postForObject()、postForEntity() 等,以及一些辅助方法,如 exchange()、execute() 等。这些方法都非常灵活,可以根据具体需求选择使用。

另外,通过为 RestTemplate 配置相应的拦截器和错误处理器,我们还可以对请求和响应进行进一步的处理。这使得我们可以更加精细地控制 HTTP 请求过程中的各个环节,并对错误进行处理。

总之,RestTemplate 是一个功能强大且易于使用的 HTTP 请求工具,特别适合用于开发基于 RESTful 风格的 Web 服务的客户端。

Feign

Fegin 的调用最大的便利之处在于,屏蔽底层的连接逻辑,让你可以像调用本地接口一样调用第三方服务,代码量更少更优雅。当然,必须在服务注册中心的协调下才能正常完成服务调用(如果不在同一注册中心下的服务/不同的项目,则需要其他的 HTTP 客户端工具,如 Apache HttpClient 和 RestTemplate),而 RestTemplate 并不关心服务注册心是否正常运行。

Feign 是由 Netflix 开发出来的另外一种实现负载均衡的开源框架,它封装了 Ribbon 和 RestTemplate,实现了 WebService 的面向接口编程,进一步的减低了项目的耦合度,因为它封装了 Riboon 和 RestTemplate ,所以它具有这两种框架的功能。 在会员模块的 pom.xml 中添加 jar 引用:

1
2
3
4
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>

客户端的模块启动类(接口调用方一般称为客户端)中增加 @EnableFeignClients 注解,才能正常使用 Feign 相关功能,启动时开启对 @FeignClient 注解的包扫描,并且扫描到相关的接口客户端。如下面的调用,parking-member 是客户端,而 parking-credit 是接口提供方:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
//parking-member 启动类
@EnableFeignClients(basePackages = "com.flameking.parking.member.client")
public class ParkingMemberApplication {
    public static void main(String[] args) {
        SpringApplication.run(ParkingMemberApplication.class, args);
    }
}

//待扫描的 parking-credit 接口
@FeignClient("paring-credit")
public interface CreditClient {
    /**
     * 添加积分交易流水记录
     *
     * @param creTransaction
     * @return 新添加记录的ID
     */
    @PostMapping("/api/creTransaction/create")
    CommonResult<String> insert(@Valid @RequestBody CreTransactionDTO creTransaction);
}

使用 IDEA 运行类似的程序时有一个缺陷:一旦接口提供方代码发生了变化就需要按照提供方 -> 客户端的次序分别对服务进行重启。这样在测试代码的时候就非常的浪费时间(未找到解决方案

本文由作者按照 CC BY 4.0 进行授权

服务多不易管理如何破——服务注册与发现

桥接模式