版权声明:本文为博主原创文章,未经博主允许不得转载。
https://blog.csdn.net/love0and1/article/details/97988367
一、在父工程中新建Common-Feign模块(建议新建maven模块,在微服务构建中一般Feign是公共的模块)
1. pom.xml中引用Feign依赖
<packaging>jar</packaging>
<artifactId>common-feign</artifactId>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<dependencies>
坑一:Feign依赖中包含了feign-hystrix熔断,不需要再引入hystrix依赖
2. 新建Feign的核心接口,针对自身项目中的不同模块新建不同的Feign,在此我以service-user模块为例
@FeignClient(value = "${userservice.service.name}",fallbackFactory = ServiceUserFeignFallbackFactory.class)
public interface ServiceUserFeign {
/**
* 查询用户信息
* (举例:针对service-user模块中controller中的searchALL方法)
* @param userSearch
* @return
*/
@RequestMapping(value = "/user/search",method = RequestMethod.GET)
public ResponseMessage searchALL(@RequestBody UserSearch userSearch);
}
该接口作用就是 通过外部调用接口,可以通过Feign映射到service-user模块下面的/user/search如下:
@RequestMapping(value = "/user")
@RestController
public class UserController {
@Autowired
private UserService userService;
@ApiOperation(value = "分页查询用户列表")
@RequestMapping(value = "/search")
public ResponseMessage searchALL(@RequestBody UserSearch userSearch) {
try {
Thread.sleep(10000);//用于请求超时,服务降级(熔断)
} catch (InterruptedException e) {
e.printStackTrace();
}
return this.userService.searchPaging(userSearch);
}
}
坑二:在UserController 和Feign核心接口ServiceUserFeign 中,如果方法参数是对象,
一定要加@RequestBody注解,否则会报错,或者参数传递不进来,如果是基本数据类型
或者string则用@RequesParam(value=" ")
3.针对自身项目中每个模块新建一个FallbackFactory类以及一个Fallback接口,作用就是Hystrix服务降级(熔断)
- Fallback接口要继承Feign核心接口
public interface ServiceUserFeignFallback extends ServiceUserFeign {
}
坑三:ServiceUserFeignFallback 就是ServiceUserFeignFallbackFactory提供一个
切面代理接口,如果不建ServiceUserFeignFallback 接口,可能会报代理切面找不到相关接口错误,spring默认的动态代理是java自带的proxy,需要接口。
- ServiceUserFeignFallbackFactory 实现FallbackFactory重写方法
Component
public class ServiceUserFeignFallbackFactory implements FallbackFactory<ServiceUserFeign> {
protected Logger logger = LogManager.getLogger(this.getClass());
@Value("${userservice.service.name}")
private String userServiceName;//这是注入的服务id名称
@Override
public ServiceUserFeign create(Throwable throwable) {
return new ServiceUserFeignFallback(){
@Override
public ResponseMessage searchALL(UserSearch userSearch) {
logger.error(userServiceName+" post /user/search",throwable);
return “熔断,服务错误。。。。”;//这里可以根据业务返回错误信息或错误页面
}
};
}
二、在父工程中新建Service-uer服务模块(三层架构springMVC就不做过多介绍)
1. pom.xml中引用相关依赖
<artifactId>service-user</artifactId>
<properties>
<java.version>1.8</java.version>
<spring-cloud.version>Finchley.RELEASE</spring-cloud.version>
</properties>
<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-server</artifactId>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
</dependency>
<dependency>
<groupId>aopalliance</groupId>
<artifactId>aopalliance</artifactId>
</dependency>
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>com.hxzy</groupId>
<artifactId>common-core</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>com.hxzy</groupId>
<artifactId>common-feign</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
</dependencies>
<!--这是父项目依赖,具体参考微服务搭建父项目-->
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<finalName>user-service</finalName>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
2. 配置文件application-user.yal
spring:
application:
name: service-user
server:
port: 9101
eureka:
client:
service-url:
defaultZone: http://server01:10086/eureka #这是注册中心服务地址
ailibaba:
durid:
url: #数据库连接地址
username: root
password: root
maxActive: 20
maxWait: 10000
minIdle: 3
validationQuery: SELECT 'x'
timeBetweenEvictionRunsMillis: 60000
minEvictableIdleTimeMillis: 300000
borrowConnectionTimeout: 30000
userservice:
service:
name: service-user #这里就是对应第一步中的第2部分${userservice.service.name}
mybatis:
mapper-locations: classpath:mapper/*.xml
type-aliases-package: com.hxzy.userservice.entity
config-location: classpath:mybatis-config.xml
3. service-user启动类
@SpringBootApplication
@EnableDiscoveryClient
@EnableFeignClients(basePackages = {"com.hxzy"})
@MapperScan(basePackages = "扫包mapper")
public class UserServiceApplication {
public static void main(String[] args) {
SpringApplication.run(UserServiceApplication.class,args);
}
}
3. service-user服务模板的Controller
@RequestMapping(value = "/user")
@RestController
public class UserController {
@Autowired
private UserService userService;
@RequestMapping(value = "/search")
public ResponseMessage searchALL(@RequestBody UserSearch userSearch) {
try {
Thread.sleep(10000);//用于测试服务连接超时降级
} catch (InterruptedException e) {
e.printStackTrace();
}
return this.userService.searchPaging(userSearch);
}
}
如果要测试Hystrix两种方式
第一:停掉Service-user服务 熔断
第二;设置连接超时时间 服务降级
坑四:出现hytrix为空null如下错误
解决方案:hytrix的超时时间一定要大于ribbon的超时时间
feign.hystrix.enabled=true
hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds=40000
ribbon.ReadTimeout= 4000
ribbon.ConnectTimeout:=4000