5、集成openfeign
5.1、服务调用方导入依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-loadbalancer</artifactId>
</dependency>
5.2、使用示例
5.2.1、服务提供方Controller
@RestController
public class StockController {
@Autowired
StockMapper stockMapper;
@PostMapping("/add")
public int add(@RequestParam("orderId") Long id) {
Stock select = stockMapper.select();
int x = stockMapper.update(id);
System.out.println(select);
return x;
}
@PostMapping(value = "/sqlFile")
public String genSqlFile(@RequestParam("sqlId")String sqlId,@RequestParam("sql")String sql){
MyTest test = new MyTest(sqlId,sql);
System.out.println(test);
return test.toString();
}
}
5.2.2、调用方Feign接口
/**
* name 指定调用服务提供方接口所对应的服务名
* path 指定调用接口所在StockController指定的@RequestMapping("/stock"),如果没有则不需要
* contextId 多个feign接口使用@FeignClient注解调用同一个名称的微服务时增加contextId属性,
* 确保每个feignclient的contextId唯一
*/
@FeignClient(name = "stock-db",contextId = "stock-db")
public interface StockFeignService {
@PostMapping("/add")
public int add(@RequestParam("orderId") Long orderId);
@PostMapping(value = "/sqlFile")
public String genSqlFile(@RequestParam("sqlId")String sqlId,@RequestParam("sql")String sql);
5.2.3、使用@EnableFeignClients开启Feign
@SpringBootApplication
@EnableDiscoveryClient //高版本可省略
@EnableFeignClients
public class OrderApplication {
public static void main(String[] args) {
SpringApplication.run(OrderApplication.class);
}
}
5.2.4、调用方service
@RestController
public class OrderController {
@Autowired
StockFeignService stockFeignService;
@GetMapping("add2/{orderId}")
public int add2(@PathVariable("orderId") Long orderId) {
return stockFeignService.add(orderId);
}
@PostMapping(value = "/sqlFile")
public String genSqlFile(@RequestParam("sqlId")String sqlId,@RequestParam("sql")String sql){
MyTest test = new MyTest(sqlId,sql);
String msg = stockFeignService.genSqlFile(test.getSqlId(),test.getSql());
System.out.println(msg + "调用成功啦!!!");
return msg;
}
}
5.5、openfeign日志配置示例
5.5.1、使用配置文件
feign:
client:
config:
# 全局使用default,指定feign默认使用feignName,如果配置了contextId必须使用contextId
stock: #@FeignClient(name = "stock-service",path = "/stock",contextId = "stock")
# 连接超时时间,默认2s
connectTimeout: 5000
# 请求处理超时时间,默认5秒
readTimeout: 3000
# 指定feign拦截器
requestInterceptors[0]: com.wanqi.interceptor.FeignInterceptor
# 指定日志级别,需要开启spring日志
loggerLevel: BASIC
# 开启Spring日志
logging:
level:
com.wanqi.feign: debug #指定feign包的日志级别为debug
5.5.2、使用注解
- 全局配置直接使用@Configuration
/**
* 全局配置直接使用 @Configuration
* 局部配置配合@FeignClient使用:configuration = FeignConfig.class
*/
@Configuration
public class FeignConfig {
/**
* NONE【性能最佳,适用于生产】:不记录任何日志(默认值)
* BASIC【适用于生产环境追踪问题】:仅记录请求方法、URL、响应状态代码以及执行时间。
* HEADERS:记录BASIC级别的基础上,记录请求和响应的neader。
* FULL【比较适用于开发及测试环境定位问题】:记录请求和响应的header、body和元数据。
*/
@Bean
public Logger.Level feignLoggerLevel(){
return Logger.Level.FULL;
}
}
- 局部配置,去掉FeignConfig配置类上的@Configuration注解,在需要指定的FeignClient属性上加上configuration = FeignConfig.class(FeignConfig配置类不要加@Configuration注解,否则这将是一个全局配置)。
/**
* name 指定调用rest接口所对应的服务名
* path 指定调用接口所在StockController指定的@RequestMapping("/stock")
* contextId 多个feign接口使用@FeignClient注解调用同一个名称的微服务时增加contextId属性,
* 确保每个feignclient的contextId唯一
* configuration 引入配置类
*/
@FeignClient(name = "stock-service",path = "/stock"
,contextId = "stock"
,configuration = FeignConfig.class
)
public interface StockFeignService {
// 接口方法对应调用服务的方法,即对应服务Controller里面的方法名和参数一一对应
@RequestMapping("/add2")
String add2();
/* @RestController
@RequestMapping("/stock")
public class StockController {
@Value("${server.port}")
private String port;
@RequestMapping("/add2")
public String add2(){
System.out.println("add2");
return "add2---" + port;
}
*/
}
5.6、feign自定义拦截器,实现RequestInterceptor接口重写apply方法,注册bean
- 自定义拦截器
public class FeignInterceptor implements RequestInterceptor {
Logger logger = LoggerFactory.getLogger(this.getClass());
@Override
public void apply(RequestTemplate requestTemplate) {
logger.info("--------------FeignInterceptor---------------" + requestTemplate.path());
logger.info("--------------FeignInterceptor---------------" + requestTemplate.request().url());
logger.info("--------------FeignInterceptor---------------" + requestTemplate.url());
}
}
- 配置类@Bean注册,或者直接在自定义拦截器上加上@Component注解(全局配置)
/**
* 自定义拦截器
*/
@Bean
public FeignInterceptor feignInterceptor(){
return new FeignInterceptor();
}
- application.yml配置文件注册(可以指定具体FeignClient)
feign:
client:
config:
# 全局使用default,指定feign默认使用feignName,如果配置了contextId必须使用contextId
stock: #@FeignClient(name = "stock-service",path = "/stock",contextId = "stock")
# 指定feign拦截器
requestInterceptors[0]: com.wanqi.interceptor.FeignInterceptor
- 使用FeignClient属性configuration配置(可以指定具体FeignClient)
/**
* name 指定调用rest接口所对应的服务名
* path 指定调用接口所在StockController指定的@RequestMapping("/stock")
* contextId 多个feign接口使用@FeignClient注解调用同一个名称的微服务时增加contextId属性,
* 确保每个feignclient的contextId唯一
* configuration 引入配置类
*/
@FeignClient(name = "stock-service",path = "/stock"
,contextId = "stock"
,configuration = {FeignConfig.class, FeignInterceptor.class}
)
public interface StockFeignService {
// 接口方法对应调用服务的方法,即对应服务Controller里面的方法名和参数一一对应
@RequestMapping("/add2")
String add2();
/* @RestController
@RequestMapping("/stock")
public class StockController {
@Value("${server.port}")
private String port;
@RequestMapping("/add2")
public String add2(){
System.out.println("add2");
return "add2---" + port;
}
*/
}
5.7、feign超时时间配置
- 配置类的方式
/**
* 超时时间配置
*/
@Bean
public Request.Options options(){
return new Request.Options(5, TimeUnit.SECONDS,10,TimeUnit.SECONDS,true);
}
- application.yml配置文件
feign:
client:
config:
# 全局使用default,指定feign默认使用feignName,如果配置了contextId必须使用contextId
product:
# 连接超时时间,默认2s
connectTimeout: 5000
# 请求处理超时时间,默认5秒
readTimeout: 3000
6、Nacos-config配置使用
- 建议所有配置文件的名字即data-id都加上文件扩展名如:test.properties,test.yml等
6.1、pom文件导入依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
<!-- 新版nacos-config要使用bootstrap.yml必须引入 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bootstrap</artifactId>
</dependency>
6.2、编写bootstrap.yml文件
6.2.1、推荐模式根据namespace来控制不同环境的配置
spring:
cloud:
nacos:
config:
server-addr: 172.16.156.137:8847
# 指定命名空间,不明确配置的话,默认是public
namespace: dev
# 指定文件名即配置的Data ID
name: com.wanqi.config-mac.yml
username: nacos
password: nacos
# 配置文件类型
file-extension: yml
6.2.2、支持profile粒度的配置
配置文件名com.wanqi.config-mac.yml,必须显示的指定文件格式
profile粒度的配置dataid即文件名格式:${spring.application.name}-${profile}.${file-extension:properties}
${spring.application.name}对应:com.wanqi.config,属性名spring.cloud.nacos.config.name
${profile}对应:mac,属性名springprofiles.active
${file-extension:properties}对应:yml,属性名spring.cloud.nacos.config.file-extension
spring:
cloud:
nacos:
config:
server-addr: 172.16.156.137:8847
# 指定命名空间,不明确配置的话,默认是public
namespace: dev
#配置文件名即Data ID为com.wanqi.config-mac.yml
# 指定文件名${spring.application.name}=com.wanqi.config
name: com.wanqi.config
username: nacos
password: nacos
# 配置文件类型${file-extension:properties}=yml
file-extension: yml
# profile粒度${profile}=mac
profiles:
active: mac
6.2.3、多配置、共享配置bootstrap.yml
:::info
shared-configs:共享配置
extension-configs:本应用所属配置
:::
spring:
cloud:
nacos:
config:
server-addr: 172.16.156.137:8847
# 指定命名空间,不明确配置的话,默认是public
namespace: test
# 指定文件名
# name: com.wanqi.config
username: nacos
password: nacos
# 配置文件类型
file-extension: yml
# shared-configs[0]:
# data-id: test.properties
# refresh: true
# shared-configs[1]:
# data-id: test01.properties
# refresh: true
shared-configs:
- data-id: test.properties
# 不明确配置的话,默认是 DEFAULT_GROUP。
# group: DEFAULT_GROUP
# refresh是否支持应用中可动态刷新, 感知到最新的配置值。默认是不支持的。
refresh: true
# 配置文件按照什么格式解析(默认properties)
# file-extension: properties
# - data-id: test01.properties
# refresh: true
extension-configs:
- data-id: test01.properties
refresh: true
6.2.4、配置中心于注册中心可支持分开部署
- 依赖
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
spring:
application:
name: test
cloud:
nacos:
config:
username: nacos
password: nacos
# 配置中心地址
# server-addr: 172.16.156.157:8848
name: test
file-extension: properties
# 注册中心地址
# discovery:
# server-addr: 172.16.156.158:8848
# 配置中心和注册中心地址一致时可以只配次项
server-addr: 172.16.156.157:8848
6.3、使用
6.3.1、硬编码
@SpringBootApplication
public class NacosConfigApplication {
public static void main(String[] args) {
ConfigurableApplicationContext context = SpringApplication.run(NacosConfigApplication.class, args);
String name = context.getEnvironment().getProperty("wq.name");
System.out.println(name);
}
}
6.3.2、注解@RefreshScope和 @Value
@Controller
@RefreshScope
public class NacosController {
@Value("${wq.name}")
private String name;
@Value("${wq.age}")
private int age;
@Value("${wq.msg}")
private String msg;
@ResponseBody
@RequestMapping("nacos")
public String nacos(){
return name + msg;
}
}
6.4、配置的优先级
Spring Cloud Alibaba Nacos Config 目前提供了三种配置能力从 Nacos 拉取相关的配置。
A: 通过 spring.cloud.nacos.config.shared-configs[n].data-id 支持多个共享 Data Id 的配置
B: 通过 spring.cloud.nacos.config.extension-configs[n].data-id 的方式支持多个扩展 Data Id 的配置
C: 通过内部相关规则(应用名、应用名+ Profile )自动生成相关的 Data Id 配置
当三种方式共同使用时,他们的一个优先级关系是:A < B < C
- 多个 Data Id 同时配置时,他的优先级关系是 spring.cloud.nacos.config.extension-configs[n].data-id 其中 n 的值越大,优先级越高。
springcloudalibaba入门(一)
springcloudalibaba入门(三)
springcloudalibaba入门(四)