服务提供与消费(下篇)
第一篇主要介绍服务注册中心,对常见几种注册中心进行了对比,主要介绍了Eureka的架构,并搭建了一个最简单的注册中心,第二篇则主要介绍注册中心的使用,上篇主要介绍服务提供者,下篇介绍服务消费者
服务消费者 - consumer
假设有一个电商交易系统,其中user-service为用户基础服务,供前端展示系统mall-admin调用
user-service 只提供一个简易的查询服务,根据输入的用户ID(userId)和用户名(username)返回json格式的用户信息
mall-admin 则作为一个后台管理系统,调用user-service的相关接口
Feign详解
在使用Spring Cloud开发微服务应用时,各个服务提供者是以HTTP接口的形式对外提供服务,因此在服务消费者调用服务提供者时,底层是通过HTTP Client的方式访问,也可以使用JDK原生的URLConnection、Apache的HTTP Client、Netty的异步HTTP Client,Spring的RestTemplate去实现服务间的调用。但是最方便、最优雅的方式是通过Spring Cloud Open Feign进行服务间调用,Spring Cloud对Feign进行了增强,使Feign支持Spring MVC注解,并整合了Ribbon等,从而让Feign的使用更加方便
Feign特性
- 可插拨的注解支持,包括Feign注解和JAX-RS注解
- 支持可插拔的HTTP编码器和解码器
- 支持Hystrix和它的Fallback
- 支持Ribbon的负载均衡
- 支持HTTP请求和响应的压缩
Feign工作原理
- 主程序入口添加@EnableFeignClients注解开启对Feign Client扫描加载处理,根据Feign Client的开发规范,定义接口并加@FeignClients注解
- 当程序启动时,会进行包扫描,扫描所有@FeignClients的注解的类,并将这些信息注入Spring IOC容器中,当定义的Feign接口中的方法被调用时,通过JDK的代理的方式,来生成具体的RequestTemplate。当生成代理时,Feign会为每个接口方法创建一个RequestTemplate对象,该对象封装了HTTP请求需要的全部信息,如请求参数名、请求方法等信息都是在这个过程中确定的
- 然后由RequestTempate生成Request,然后把Request交给Client去处理,这里指的Client可以是JDK原生的URLConnection、Apache的HTTP Client,也可以是Okhttp,最后Client被封装到LoadBalanceClient类,这个类结合Ribbon负载均衡发起服务之间的调用。
本篇mall-admin(服务调用)将使用Spring Cloud Open Feign调用user-srvice(服务提供者)
项目实战
代码及配置
pom.xml
<parent>
<artifactId>spring-cloud</artifactId>
<groupId>com.kk</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>mall-admin</artifactId>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
</dependencies>
parent pom.xml
parent pom同第一篇,详情可直接参考github中代码
启动类
启动类添加@EnableDiscoveryClient和@EnableFeignClients注解
@EnableDiscoveryClient
@EnableFeignClients
@SpringBootApplication
public class MallAdminApplication {
public static void main(String[] args) {
SpringApplication.run(MallAdminApplication.class, args);
}
}
* @EnableDiscoveryClient 启用服务注册与发现
* @EnableFeignClients 启用feign进行远程调用
Feign是一个声明式Web Service客户端。使用Feign能让编写Web Service客户端更加简单, 它的使用方法是定义一个接口,然后在上面添加注解,同时也支持JAX-RS标准的注解。Feign也支持可拔插式的编码器和解码器。Spring Cloud对Feign进行了封装,使其支持了Spring MVC标准注解和HttpMessageConverters。Feign可以与Eureka和Ribbon组合使用以支持负载均衡。
feign service
@FeignClient(name = "user-service")
public interface UserFeignService {
@RequestMapping(value = "/user/info")
public String userInfo(@RequestParam(value = "userName") String userName, @RequestParam(value = "age") int age);
}
name: 远程服务名,及spring.application.name配置的名称
此类中的方法和远程服务中controller中的方法名(/user/info)和参数(userName, age)需保持一直
接口类
@RestController
@RequestMapping("/admin-user")
public class UserController {
@Autowired
private UserFeignService userFeignService;
@RequestMapping("/info")
public String userInfoAction(@RequestParam(value = "userName") String userName,
@RequestParam(value = "age") int age) {
return userFeignService.userInfo(userName, age);
}
}
将UserFeignService注入到controller层,就可以像普通方法一样去调用了
配置文件 application.yml
server:
port: 8092
spring:
application:
name: mall-admin # 在注册中心中显示和调用的名称
eureka:
client:
service-url:
defaultZone: http://localhost:8090/eureka/ # 将自己注册到该地址的Eureka上面去
测试
注册中心、服务提供者、服务消费者均已开发、配置完成,可以进行简要测试
依次启动eureka-server、user-service和mall-admin服务
启动界面
eureka-server可以看到user-service、mall-admin已成功注册到注册中心(eureka-server)
测试验证
在浏览器或postman等工具输入:http://192.168.31.174:8091/user/info?userName=Jack&age=18检查服务提供者(user-service)是否正常,运行成功返回如下信息
然后再输入:http://192.168.31.174:8092/admin-user/info?userName=Jack&age=18 检查服务消费者(mall-admin)是否正常,运行成功返回如下信息,说明服务消费者已成功的通过feign调用了远程服务(服务提供者)提供的服务/user/info,并且将结果返回到了浏览器