OpenFeign使用
- Feign和OpenFeign
- 实现OpenFeign功能
- 远程服务调用
- 启动类加载feign
- 创建common公共模块
- 使用远程调用
- user服务中提供接口
- 远程服务调用结果
- get请求带参数问题
- 负载均衡
- ribbon方式
- springCloud LoadBalancer
- 身份验证
- 服务提供者开启身份证验证
- 服务调用方添加验证信息
- 直接添加
- 配置文件方式
- 原理
- 代码地址
OpenFeign是Netflix 开发的声明式、模板化的HTTP请求客户端。可以更加便捷、优雅地调用http api。就是解决微服务之间rest接口调用问题和RestTemplate做的事情有点像,feig是专业的服务之间调用RestTemplate只是业余,不过他们都实现服务之间调用,并且都很好集成了Ribbon和Hystrix可以实现负载均衡和断路器。
Feign和OpenFeign
Feign本身不支持Spring MVC的注解,它有一套自己的注解。
OpenFeign是Spring Cloud 在Feign的基础上支持了Spring MVC的注解。只需在接口类上使用@FeignClient就可以使用@RequestMapping等springMVC的注解。通过动态代理使用@FeignClient注解,在代理类中进行负载均衡和服务调用功能。
实现OpenFeign功能
远程服务调用
启动类加载feign
1
2
3
4@SpringBootApplication @EnableFeignClients public class EurekaConsumer2Application {}
创建common公共模块
为什么会用公共模块,这个模块主要定义服务之间调用的接口格式,URL、请求参数DTO、响应参数DTO等公服务。
定义接口类和使用feign类
1
2
3
4
5
6
7
8
9
10
11
12
13package com.example.common.api.user.controller; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; public interface UserApi { @RequestMapping("/userInfo") public String userInfo(@RequestBody long userId); }
1
2
3
4
5
6
7
8
9package com.example.common.api.user.server; import com.example.common.api.user.controller.UserApi; import org.springframework.cloud.openfeign.FeignClient; @FeignClient(name="user") public interface UserClient extends UserApi { }
添加openfeign依赖
1
2
3
4
5<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-openfeign</artifactId> </dependency>
使用远程调用
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35package com.example.eureka_consumer2.controller; import com.example.common.api.user.server.UserClient; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @RestController public class TestController{ /* @Autowired private RestTemplate restTemplate;*/ @Autowired private UserClient userClient; /*@RequestMapping("/getUser") public String getUser(){ //http:使用负载均衡rest请求就需要指定实例信息 // //restTemplate.getForObject("//windows10.microdone.cn:8000/toUser",String.class) //如果使用ribbon 负载进行就使用服务名进行调用 String str = restTemplate.getForObject("http://user/toUser",String.class); System.out.println(str); return str; }*/ @RequestMapping("/getUserInfo") public String getUserInfo(){ String str = userClient.userInfo(1); System.out.println(str); return str; } }
user服务中提供接口
接口类使用common的UserApi接口
1
2
3
4
5
6
7
8
9
10
11
12
13
14package com.example.eureka_client_user_1.Controller; import com.example.common.api.user.controller.UserApi; import org.springframework.web.bind.annotation.RestController; @RestController public class UserController implements UserApi { @Override public String userInfo(long userId) { return "user1"+userId; } }
远程服务调用结果
get请求带参数问题
Feign默认所有带参数的请求都是Post。feign默认使用的JDK的URLHttpConnection请求,所有会存在这个问题。建议换成httpclient就可以了。
1
2
3
4
5
6<!-- openfeign的http请求工具类修改httpclient --> <dependency> <groupId>io.github.openfeign</groupId> <artifactId>feign-httpclient</artifactId> </dependency>
负载均衡
新版springCloud默认是不支持netflix的ribbon,使用的springCloud LoadBalancer进行负载均衡。
可以参考ribbon使用
ribbon方式
我的例子中eureka_consumer2使用ribbon进行负载均衡。springCloud版本是Hoxton.SR3。
添加依赖
1
2
3
4
5<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-ribbon</artifactId> </dependency>
配置文件选择策略
默认是轮询策略
1
2
3#设置user服务为随机策略 user.ribbon.NFLoadBalancerRuleClassName=com.netflix.loadbalancer.RandomRule
springCloud LoadBalancer
可以参考官网文档spring-cloud-commons。
提供两种策略基于循环和随机。因为循环的默认策略,我就写一下怎么改成随机策略。
创建随机策略bean配置 CustomLoadBalancerConfiguration类
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23package com.example.eureka_consumer.config; import org.springframework.cloud.client.ServiceInstance; import org.springframework.cloud.loadbalancer.core.RandomLoadBalancer; import org.springframework.cloud.loadbalancer.core.ReactorLoadBalancer; import org.springframework.cloud.loadbalancer.core.ServiceInstanceListSupplier; import org.springframework.cloud.loadbalancer.support.LoadBalancerClientFactory; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.core.env.Environment; @Configuration public class CustomLoadBalancerConfiguration { @Bean ReactorLoadBalancer<ServiceInstance> randomLoadBalancer(Environment environment, LoadBalancerClientFactory loadBalancerClientFactory) { String name = environment.getProperty(LoadBalancerClientFactory.PROPERTY_NAME); return new RandomLoadBalancer(loadBalancerClientFactory .getLazyProvider(name, ServiceInstanceListSupplier.class), name); } }
启动类上加载 LoadBalancerClient的策略
1
2
3
4
5@SpringBootApplication @EnableFeignClients @LoadBalancerClient(value = "user",configuration = CustomLoadBalancerConfiguration.class) public class EurekaConsumerApplication {}
身份验证
服务接收的rest请求进行身份证认证,这是spring security的一种安全验证方式。当服务提供方开启验证,那么服务调用方就需要在调用服务时候就需要添加验证信息,保证的验证成功。
服务提供者开启身份证验证
加载依赖
1
2
3
4
5
6<!--安全验证--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-security</artifactId> </dependency>
配置加载
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23package com.example.eureka_client_user_1.config; import org.springframework.context.annotation.Configuration; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; import org.springframework.security.config.http.SessionCreationPolicy; @Configuration @EnableWebSecurity public class WebSecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { // 关闭csrf http.csrf().disable(); // 表示所有的访问都必须认证,认证处理后才可以正常进行 http.httpBasic().and().authorizeRequests().anyRequest().fullyAuthenticated(); // 所有的rest服务一定要设置为无状态,以提升操作效率和性能 http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS); } }
配置文件中配置安全验证用户信息
1
2
3
4#安全验证 spring.security.user.name=root spring.security.user.password=root
服务调用方添加验证信息
可以在使用@FeignClient注解时直接添加验证信息,也可以通过配置文件配置方式。
直接添加
直接添加配置类
1
2
3
4
5
6
7
8
9package com.example.common.api.user.server; import com.example.common.api.user.controller.UserApi; import org.springframework.cloud.openfeign.FeignClient; @FeignClient(name="user",configuration = UserFeignAuthConfiguration.class) public interface UserClient extends UserApi { }
添加配置类
1
2
3
4
5
6
7
8
9
10
11
12
13
14package com.example.common.config.auth; import feign.auth.BasicAuthRequestInterceptor; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration public class UserFeignAuthConfiguration { @Bean public BasicAuthRequestInterceptor basicAuthRequestInterceptor() { return new BasicAuthRequestInterceptor("root", "root"); } }
配置文件方式
创建request拦截器,在拦截器中添加验证信息。
1
2
3
4
5
6
7
8
9
10
11
12
13package com.example.common.config.auth.interceptor; import feign.RequestInterceptor; import feign.RequestTemplate; public class MyBasicAuthRequestInterceptor implements RequestInterceptor { @Override public void apply(RequestTemplate requestTemplate) { requestTemplate.header("Authorization", "Basic cm9vdDpyb290"); } }
添加配置信息
1
2
3
4
5
6
7
8#feign 配置 #手动配置拦截器 添加请求鉴权信息 feign.client.config.user.request-interceptors[0]=com.example.common.config.auth.interceptor.MyBasicAuthRequestInterceptor #连接超时 feign.client.config.user.connect-timeout=5000 #请求超时 feign.client.config.user.read-timeout=5000
原理
- 主程序入口添加@EnableFeignClients注解开启对Feign Client扫描加载处理。根据Feign Client的开发规范,定义接口并加@FeignClient注解。
- 当程序启动时,会进行包扫描,扫描所有@FeignClient注解的类,并将这些信息注入Spring IoC容器中。当定义的Feign接口中的方法被调用时,通过JDK的代理方式,来生成具体的RequestTemplate。当生成代理时,Feign会为每个接口方法创建一个RequestTemplate对象,该对象封装了HTTP请求需要的全部信息,如请求参数名、请求方法等信息都在这个过程中确定。
- 然后由RequestTemplate生成Request,然后把这个Request交给client处理,这里指的Client可以是JDK原生的URLConnection、Apache的Http Client,也可以是Okhttp。最后Client被封装到LoadBalanceClient类,这个类结合Ribbon负载均衡发起服务之间的调用。
代码地址
https://gitee.com/zhang798/spring-cloud/tree/feign
分支:feign
1
2git clone https://gitee.com/zhang798/spring-cloud.git -b feign
最后
以上就是怕孤单小刺猬最近收集整理的关于OpenFeign使用的全部内容,更多相关OpenFeign使用内容请搜索靠谱客的其他文章。
发表评论 取消回复