上节笔记整理到如何进行服务之间的调用,这次结合Feign对服务进行调用,以及服务降级处理
首先我们看一下这次服务调用,先看下项目结构:
image我们从注册中心依次叙述到服务调用
yyc父项目模块中的pom文件
在父项目中分别定义了Eureka注册中心ycc-registry,模块yyc-test以及模块yyc-demo
这次使用中将yyc-test作为服务的提供者,yyc-demo作为服务的消费者
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.zhaixingzu</groupId>
<artifactId>yyc</artifactId>
<version>1.1.0-SNAPSHOT</version>
<packaging>pom</packaging>
<name>yyc</name>
<description>yyc-pom</description>
<modules>
<module>yyc-registry</module>
<module>yyc-test</module>
<module>yyc-demo</module>
</modules>
<!-- 集中定义版本号 -->
<properties>
<spring-boot.version>2.1.3.RELEASE</spring-boot.version>
<spring-cloud.version>Greenwich.RELEASE</spring-cloud.version>
<spring-boot-admin.version>2.1.3</spring-boot-admin.version>
</properties>
<dependencies>
<!--eureka 客户端-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<!--测试依赖-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!--监控-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<!--断路器依赖-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
<!--监控客户端-->
<dependency>
<groupId>de.codecentric</groupId>
<artifactId>spring-boot-admin-starter-client</artifactId>
<version>${spring-boot-admin.version}</version>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>${spring-boot.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<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>
</project>
yyc-registry中的pom文件
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.zhaixingzu</groupId>
<artifactId>yyc</artifactId>
<version>1.1.0-SNAPSHOT</version>
</parent>
<artifactId>yyc-register</artifactId>
<packaging>jar</packaging>
<name>yyc-register</name>
<description>yyc 注册中心</description>
<dependencies>
<!--服务中心-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
<!--security-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-security</artifactId>
</dependency>
<!--web 模块-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<!--排除tomcat依赖-->
<exclusion>
<artifactId>spring-boot-starter-tomcat</artifactId>
<groupId>org.springframework.boot</groupId>
</exclusion>
</exclusions>
</dependency>
<!--undertow容器-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-undertow</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
yyc-registry注册中心的配置信息
server:
port: 9900
spring:
application:
name: yyc-registry
security:
user:
name: admin
password: admin
cloud:
config:
enabled: false
eureka:
instance:
hostname: 127.0.0.1
prefer-ip-address: true
server:
#是否开启自我保护(运行期间spring会统计信条失败的比例在15分钟之内是否低于85%,如果不低于85%,Eureka会将实例注册信息保护起来,让这些实例不会过期)
enable-self-preservation: false
eviction-interval-timer-in-ms: 3000 #3秒钟自动剔除失效的节点,清理无效的节点
response-cache-update-interval-ms: 3000 #eureka server刷新readCacheMap的时间,注意,client读取的是readCacheMap,这个时间决定了多久会把readWriteCacheMap的缓存更新到readCacheMap上
response-cache-auto-expiration-in-seconds: 180
#eureka server缓存readWriteCacheMap失效时间,这个只有在这个时间过去后缓存才会失效,失效前不会更新,过期后从registry重新读取注册服务信息,registry是一个ConcurrentHashMap。
#由于启用了evict其实就用不太上改这个配置了
#默认180s
client:
register-with-eureka: false #不要向注册中心注册自己
fetch-registry: false
serviceUrl:
defaultZone: http://${spring.security.user.name}:${spring.security.user.password}@${eureka.instance.hostname}:${server.port}/eureka/ #设置与eureka交互的地址
#如果要开启全部的监听端点,可以在yml文件中加入下面的配置信息
#/actuator/health和/actuator/info以及/actuator这三个就是actuator提供的端点,
#注意以前的版本是没有/actuator前缀的,2.0以后的版本都加了/actuator前缀。
#可以访问localhost:8800/actuator尝试看监听的都是一些什么内容
management:
endpoints:
web:
exposure:
include: "*"
Eureka认证安全配置:
package com.zhaixingzu.yyc.registry.security;
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;
/**
* @author Herbert
* @date 2019/06/24
*/
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) {
try {
http.csrf().disable()
.authorizeRequests()
.antMatchers("/actuator/**").permitAll()
.anyRequest()
.authenticated().and().httpBasic();
} catch (Exception e) {
e.printStackTrace();
}
}
}
yyc-registry 注册中心启动类:
package com.zhaixingzu.yyc.registry;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;
/**
* 服务注册中心
* @author Herbert
* @date 2019年06月19日
*/
@EnableEurekaServer
@SpringBootApplication
public class RegistryApplication {
public static void main(String[] args) {
SpringApplication.run(RegistryApplication.class, args);
}
}
上述已经完全配置好注册中心,详见:
yyc-test中的pom
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.zhaixingzu</groupId>
<artifactId>yyc</artifactId>
<version>1.1.0-SNAPSHOT</version>
</parent>
<artifactId>yyc-test</artifactId>
<packaging>jar</packaging>
<name>yyc-test</name>
<description>test</description>
<dependencies>
<!--web 模块-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<!--排除tomcat依赖-->
<exclusion>
<artifactId>spring-boot-starter-tomcat</artifactId>
<groupId>org.springframework.boot</groupId>
</exclusion>
</exclusions>
</dependency>
<!--undertow容器-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-undertow</artifactId>
</dependency>
</dependencies>
</project>
yyc-test中的配置信息
server:
port: 8800
spring:
application:
name: yyc-test
eureka:
client:
serviceUrl:
defaultZone: http://admin:admin@127.0.0.1:9900/eureka/ #设置与eureka交互的地址
yyc-test中的启动类
package com.zhaixingzu.yyc.test;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
/**
*
* @author Herbert
* @date 2019年06月19日
*/
@EnableEurekaClient
@SpringBootApplication
public class TestApplication {
public static void main(String[] args) {
SpringApplication.run(TestApplication.class, args);
}
}
yyc-test中的服务提供Controller
package com.zhaixingzu.yyc.test.controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* Created by Herbert on 2019/6/24.
*/
@RestController
@RequestMapping("/test")
public class TestController {
@GetMapping("/show")
public String show(){
return "hello";
}
}
上述服务注册到注册中心已经完成,也就是服务提供者,其实他也可以去消费其他的服务
yyc-demo中的pom文件
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.zhaixingzu</groupId>
<artifactId>yyc</artifactId>
<version>1.1.0-SNAPSHOT</version>
</parent>
<artifactId>yyc-demo</artifactId>
<packaging>jar</packaging>
<name>yyc-demo</name>
<description>demo</description>
<dependencies>
<!--web 模块-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<!--排除tomcat依赖-->
<exclusion>
<artifactId>spring-boot-starter-tomcat</artifactId>
<groupId>org.springframework.boot</groupId>
</exclusion>
</exclusions>
</dependency>
<!--undertow容器-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-undertow</artifactId>
</dependency>
<!--feign 依赖-->
<dependency>
<groupId>io.github.openfeign</groupId>
<artifactId>feign-okhttp</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
</dependencies>
</project>
yyc-demo中的配置信息
server:
port: 8801
spring:
application:
name: yyc-demo
eureka:
client:
serviceUrl:
defaultZone: http://admin:admin@127.0.0.1:9900/eureka/ #设置与eureka交互的地址
feign:
hystrix:
enabled: true
yyc-demo中的启动类
package com.zhaixingzu.yyc.demo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.cloud.openfeign.EnableFeignClients;
import org.springframework.context.annotation.Bean;
import org.springframework.web.client.RestTemplate;
/**
*
* @author Herbert
* @date 2019年06月20日
*/
@EnableEurekaClient
@SpringBootApplication
@EnableFeignClients
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
// @Bean // 自动扫描
// @LoadBalanced //这个注解的意思是在启动时先加载注册中心的域名列表
// public RestTemplate restTemplate() //这个方法用来发http请求
// {
// RestTemplate restTemplate=new RestTemplate();
// return restTemplate;
// }
}
yyc-demo中的服务调用controler
package com.zhaixingzu.yyc.demo.controller;
import com.zhaixingzu.yyc.demo.feign.DemoServer;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* Created by Herbert on 2019/6/25.
*/
@RestController
@RequestMapping("/demo")
public class DemoController {
@Autowired
private DemoServer demoServer;
// private RestTemplate restTemplate;
@GetMapping("/show")
public String show(){
return demoServer.show();
}
}
下面看一下yyc-demo的结构图:
image建立feign文件,这个可以随便命名,我们写一个DemoServer中去利用Feign调用
package com.zhaixingzu.yyc.demo.feign;
import com.zhaixingzu.yyc.demo.feign.factory.DemoFeignFallbackFactory;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
/**
* Created by Herbert on 2019/6/25.
*/
@FeignClient(value = "yyc-test",fallbackFactory =DemoFeignFallbackFactory.class)
public interface DemoServer {
@GetMapping("/test/show")
String show();
}
定义DemoFeignFallbackFactory
package com.zhaixingzu.yyc.demo.feign.factory;
import com.zhaixingzu.yyc.demo.feign.DemoServer;
import com.zhaixingzu.yyc.demo.feign.fallback.DemoServerImpl;
import feign.hystrix.FallbackFactory;
import org.springframework.stereotype.Component;
/**
* Created by Herbert on 2019/6/26.
*/
@Component
public class DemoFeignFallbackFactory implements FallbackFactory<DemoServer> {
public DemoServer create(Throwable throwable) {
return new DemoServer() {
public String show() {
return "服务异常";
}
};
}
}
也可以使用fallback来进行降级处理
@FeignClient(value = "yyc-test",fallback=DemoServerImpl.class)
public interface DemoServer {
@GetMapping("/test/show")
String show();
}
fallback所对应的DemoServerImpl
package com.zhaixingzu.yyc.demo.feign.factory;
import com.zhaixingzu.yyc.demo.feign.DemoServer;
import com.zhaixingzu.yyc.demo.feign.fallback.DemoServerImpl;
import feign.hystrix.FallbackFactory;
import org.springframework.stereotype.Component;
/**
* Created by Herbert on 2019/6/26.
*/
@Component
public class DemoFeignFallbackFactory implements FallbackFactory<DemoServer> {
public DemoServer create(Throwable throwable) {
return new DemoServer() {
public String show() {
return "服务异常";
}
};
}
}
配置好了以后请求后得到正常的返回数据
image关掉yyc-test的服务,再次请求接口,会请求到降级服务
image关于Feign Hystrix回退,如果需要方位导致回退的原因,可以使用@FeignClient内的fallbackFactory属性,如果只是启用回退,可使用fallback
欢迎关注摘星族
摘星族.jpg
网友评论