赞
踩
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
server: port: 9001 spring: application: name: consumer # 应用名 cloud: nacos: discovery: server-addr: localhost:8848 # nacos服务地址 sentinel: transport: port: 8719 # 启动http server,并且该服务与Sentinel仪表板进行交互,使sentinel可以控制应用,若端口占用则8719+1依次扫描 dashboard: 127.0.0.1:8080 # 仪表版访问地址 feign: # 增加对sentinel的支持 sentinel: enabled: true
这里说一下如果不加feign.sentinel.enabled=true的配置,那么在@FeignClient中定的fallback属性定义的异常、限流等自定义的处理逻辑不会生效
@SpringBootApplication
@EnableDiscoveryClient
@EnableFeignClients
public class OrderNacosApplication{
public static void main(String[] args) {
SpringApplication.run(OrderNacosApplication.class, args);
}
}
@SpringBootApplication
@EnableDiscoveryClient
//这种方式是精准打击,只拿指定的类
//@EnableFeignClients(clients = {UserDemo.class})
//这种方式会将指定包下的所有东西都拿过来
@EnableFeignClients(basePackages = "com.alibaba.provider.feigns")
public class OrderNacosApplication{
public static void main(String[] args) {
SpringApplication.run(OrderNacosApplication.class, args);
}
}
Ps:OpenFeign早期版本(例如 2020版本以前 )要求服务提供方在1秒内处理业务逻辑并返回响应。如果超过1秒没有返回,OpenFeign会直接报错,不会等待服务执行。随着版本的更新,OpenFeign已经对此做出了调整或优化(例如 2021.0.1)
feign:
client:
config:
product-service: # 服务名
connect-timeout: 5000 # 配置指定服务连接超时时间
read-timeout: 5000 # 配置指定服务等待超时时间
stock-nacos: # 服务名
connect-timeout: 5000 # 配置指定服务连接超时时间
read-timeout: 5000 # 配置指定服务等待超时时间
feign:
client:
config:
default: # 所有服务
connect-timeout: 5000 # 配置指定服务连接超时时间
read-timeout: 5000 # 配置指定服务等待超时时间
package com.test.order.config; import feign.Request; import org.springframework.context.annotation.Bean; /** * @Description: * @Author: xu * @Data: 2024-2024/4/10-21 * @Version: V1.0 */ //@Configuration //注意: 此处配置@configuration注解就会全局生效,如果想指定对应微服务生效,就不能配置 public class FeignTimeOutConfig { @Bean public Request.Options options() { return new Request.Options(5000, 10800); } }
#开启 openfeign 日志
logging:
level:
com.test.order.feign: debug #这样打印的就只有openfeign的debug日记
#全局生效
feign:
client:
config:
default: # 所有服务生效
logger-level: FULL
#局部生效
feign:
client:
config:
product-service: #服务名
logger-level: basic
stock-nacos: #服务名
logger-level: full
package com.test.order.config; import feign.Logger; import org.springframework.context.annotation.Bean; /** * @Description: * @Author: xu * @Data: 2024-2024/4/10-17 * @Version: V1.0 */ //@Configuration //注意: 此处配置@configuration注解就会全局生效,如果想指定对应微服务生效,就不能配置 public class FeignClientConfiguration { @Bean public Logger.Level feignLogLevel(){ return Logger.Level.FULL; //一般使用 BASIC 级别,因为太多的日志信息影响效率 } }
@EnableFeignClients(defaultConfiguration = FeignClientConfiguration.class)
@FeignClient(value = "stock-nacos",path = "/stock",configuration = {FeignClientConfiguration.class})
public interface StockFeignService {
@RequestMapping("/reduce")
String reduce();
}
Feign 的底层客户端实现:
- URLConnection:默认实现,不支持连接池
- Apache HttpClient :支持连接池
- OKHttp:支持连接池
因此优化Feign的性能主要包括:
- 使用连接池代替默认的URLConnection
- 日志级别,最好用basic或none
- 因此使用 HttpClient 或 OKHttp 代替 URLConnection
<!--httpClient的依赖 -->
<dependency>
<groupId>io.github.openfeign</groupId>
<artifactId>feign-httpclient</artifactId>
</dependency>
feign:
client:
config:
default: # default全局的配置
loggerLevel: BASIC # 日志级别,BASIC就是基本的请求和响应信息
httpclient:
enabled: true # 开启feign对HttpClient的支持
max-connections: 200 # 最大的连接数
max-connections-per-route: 50 # 每个路径的最大连接数
具体的添加@LoadBalancerClient注解:在调用服务的Service类上添加@LoadBalancerClient注解,并指定服务名。这样,负载均衡器将根据配置的属性来选择合适的服务实例进行调用。例如
/**
* name:指定调用rest接口所对应的服务名
* path 指定调用rest接口所在的stockController指定的eRequestMapping
* 类上无需添加@Component注解
*/
@FeignClient(value = "stock-nacos", path = "/stock")
public interface StockFeignService{
@RequestMapping("/reduce")
String reduce();
}
package com.test.order.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.core.env.Environment; 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); } }
package com.test.order; import com.test.order.config.CustomLoadBalancerConfiguration; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.loadbalancer.annotation.LoadBalancerClient; import org.springframework.cloud.loadbalancer.annotation.LoadBalancerClients; import org.springframework.cloud.openfeign.EnableFeignClients; /** * @Description: * @Author: xu * @Data: 2024-2024/3/29-16 * @Version: V1.0 */ @SpringBootApplication @EnableFeignClients @LoadBalancerClients({@LoadBalancerClient(value = "stock-nacos", configuration = {CustomLoadBalancerConfiguration.class})}) public class OrderOpenFeignApplication { public static void main(String[] args) { SpringApplication.run(OrderOpenFeignApplication.class, args); } }
package com.test.order.config; import feign.Contract; import org.springframework.context.annotation.Bean; /** * @Description: * @Author: xu * @Data: 2024-2024/4/10-21 * @Version: V1.0 */ @Component不要使用该注解,会变成全局 public class ContractConfig { @Bean public Contract feigncontract() { return new Contract.Default(); } }
@FeignClient(value = "stock-nacos", path = "/stock" ,configuration = {ContractConfig.class})
public interface StockFeignService {
@RequestLine("GET /reduce")
String reduce();
}
#局部生效
feign:
client:
config:
product-service:
logger-level: basic
stock-nacos:
logger-level: full
contract: feign.Contract.Default #指定Feign原生注解契约配置
package com.test.order.interceptor; import feign.RequestInterceptor; import feign.RequestTemplate; /** * @Description: * @Author: xu * @Data: 2024-2024/4/10-21 * @Version: V1.0 */ public class CustomFeignAuthRequestInterceptor implements RequestInterceptor { @Override public void apply(RequestTemplate requestTemplate) { System.out.println("openfeign拦截器执行了"); requestTemplate.header("token","888"); } }
package com.test.order.config; import com.test.order.interceptor.CustomFeignAuthRequestInterceptor; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; /** * @Description: * @Author: xu * @Data: 2024-2024/4/10-21 * @Version: V1.0 */ //@Configuration //注意: 此处配置@configuration注解就会全局生效,如果想指定对应微服务生效,就不能配置 public class FeignInterceptorConfig { @Bean public CustomFeignAuthRequestInterceptor feignAuthRequestInterceptor(){ return new CustomFeignAuthRequestInterceptor(); } }
@EnableFeignClients(defaultConfiguration = FeignInterceptorConfig .class)
@FeignClient(value = "stock-nacos",path = "/stock",configuration = {FeignInterceptorConfig .class})
public interface StockFeignService {
@RequestMapping("/reduce")
String reduce();
}
feign:
client:
config:
stock-nacos:
request-interceptors:
- com.test.order.interceptor.CustomFeignAuthRequestInterceptor
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。