当前位置: 首页 > 科技观察

谈谈Http服务改造的实践

时间:2023-03-21 00:47:36 科技观察

在微服务架构体系中,远程RPC调用主要有Dubbo和Http调用。由于Dubbo有服务注册中心,服务的命名非常规范,所以使用包名.class名。描述的方法名称。HTTP调用通常会用到httpclient等相关库。使用这些没有问题,但是API分散在整个项目的各个地方。如果HTTP调用也可以使用类似Dubbo服务的表示方式,使用声明式定义即可。在开源的世界里,只有想不到的东西,没有什么可以找到的。为了解决Feign的声明式服务管理,Feign框架应运而生。本文主要介绍如何使用Feign实现Http服务的声明式管理和调用。1、什么是Feign?Feign是一个轻量级的http请求调用框架,可以通过Java接口注解的形式调用Http请求。Feign通过注解模板化请求。真正调用的时候传入参数,然后根据参数应用到请求中,然后转化为真正的请求,封装了http调用过程。2.快速入门示例2.1先定义客户端导入Feign的maven依赖,如下图:com.netflix.feignfeign-core8.18.02.2定义服务调用API(类似DubboAPI)服务调用API声明代码如下:@FeignClientpublicinterfaceHelloControllerApi{@RequestLine("GET/api/hello?name={name}")Stringhello(@Param(value="name")Stringname);}这里的重点是使用@FeignClient进行声明。声明后,就可以通过HelloControllerApi进行远程HTTP调用了。示例代码如下:publicclassHelloControllerApiTest{privateHelloControllerApiservice;@Beforepublicvoidbefore(){service=Feign.builder().options(newRequest.Options(1000,3500)).retryer(newRetryer.Default(5000,5000,3)).target(HelloControllerApi.class,"http://127.0.0.1:8080");}@Testpublicvoidhello(){//调用http://127.0.0.1:8080/api/hello?name=world的http接口System.out.println(service.hello("world"));}}当然,你需要添加@EnableFeignClients(defaultConfiguration=FeignConfiguration.class)注解。2.3定义服务器服务器与Feign无关,主要可以通过API的方式实现。服务端实现代码如下:@Controller@RequestMapping(value="api")publicclassHelloController{@RequestMapping(value="/hello",method={RequestMethod.GET})@ResponseBodypublicStringlist(@RequestParamString姓名){返回“你好”+姓名;}}//启动类@SpringBootApplication(scanBasePackages={"com.vhicool.manager"})publicclassManagerApplication{publicstaticvoidmain(String[]args){SpringApplication.run(ManagerApplication.class,args);}}3。实现签名校验上面只是一个简单实用的Feign,接下来就是实现签名校验作为例子展示Feign的扩展机制。签名验证是最常见的安全机制。首先在客户端定义一个签名拦截器来生成签名信息。示例代码如下图所示:publicclassAuthRequestInterceptorimplementsfeign.RequestInterceptor{privateTokenServicetokenService;publicAuthRequestInterceptor(TokenServicetokenService){this.tokenService=tokenService;}@Overridepublicvoidapply(RequestTemplatetemplate){template.header("token",tokenService.getToken());}}并在Feign的全局配置文件中创建对应的拦截器,示例代码如下:,示例代码如下:@ComponentpublicclassAuthFilterimplementsFilter{@AutowiredprivateTokenServicetokeService;@OverridepublicvoiddoFilter(ServletRequestservletRequest,ServletResponseservletResponse,FilterChainfilterChainin)抛出IOException,ServletException{StringremoteToken=((HttpServletRequest)servletRequest).getHeader("token");if(!tokeService.valid(token)){//异常处理逻辑return;}filterChain.doFilter(servletRequest,servletResponse);}}4。服务器自动生成Feign。上面的例子虽然实现了服务接口的声明式管理,但是调用方和客户端并没有显示的约束关系。接下来,我们将展示如何使用客户端和服务器来使用继承。定义一个服务调用API,例如实现下图效果:原生Feign无法实现这个效果,我们需要使用OpenFeign类库,两者对比如下图:,我们将详细介绍具体的实现方法。4.1提取公共API首先,使用一个模块定义公共API,需要引入maven依赖。代码示例如下:公共服务接口。客户端和服务端都需要实现这个接口。公共服务接口定义如下:publicinterfaceIUserController{@RequestMapping(value="user/list-all",method={RequestMethod.GET})ListlistAll(@RequestParamStringname);}4.2实现服务器端的公共API,首先需要添加相应的maven依赖,代码如下:org.springframework.bootspring-boot-starter-webcom.vhicoolfeign-api1.0-SNAPSHOT编译服务端通过继承实现,具体代码如下:@Controller@RequestMappingpublicclassUserControllerimplementsIUserController{@Override@ResponseBodypublicListlistAll(Stringname){ArrayListlist=newArrayList<>();list.add("达菲");list.add("olu");list.add(名字);代码如下:>junitjunit4.12编译com.vhicoolfeign-api1.0-SNAPSHOTcompile客户端服务调用类需要继承公共API:@FeignClient(value="user",url="http://localhost:8080")publicinterfaceUserApiextendsIUserController{}同时客户端启动类需要添加@EnableFeignClients注解。具体示例代码如下:@SpringBootApplication@EnableFeignClientspublicclassManagerApplication{publicstaticvoidmain(String[]args){SpringApplication.run(ManagerApplication.class,args);}}同样基于Springboot编程方式,可以为Feign配置全局参数,如下:@ConfigurationpublicclassFeignConfiguration{/***请求超时时间*@return*/@BeanpublicRequest.Optionsoptions(){returnnewRequest.Options(2000,3500);}//拦截器等定义}然后客户端可以通过以下方式调用:@RunWith(SpringRunner.class)@SpringBootTestpublicclassUserControllerTest{@AutowiredprivateUserApiuserApi;@TestpublicvoidlistAll(){System.out.println(userApi.listAll("Pies"));}},当前项目编译的jar包,类也已经替换成我们自定义的上课,目标达成作者介绍:李大伟,现任中通快递中间件高级架构师,在消息中间件和Flink方面有非常丰富的实战经验。