spring cloud 有很多组件:
hystrix , ribbon ,feign, gateway, eureka 等。
hystrix 使用(包的依赖暂时不讲)
在controller上注解 @EnableCircuitBreaker ,然后再方法上再注解 @HystrixCommand(fallbackMethod="gun") ,如:
@RestController
@EnableCircuitBreaker
public class MainController {
@RequestMapping("/fun")
@HystrixCommand(fallbackMethod="gun")
public String fun(@RequestParam String s){
System.out.println("in fun--- 9997");
if("error".equals(s)){
throw new RuntimeException("err");
}
return "ok-"+s;
}
public String gun(String m){
return "Faild"+m;
}
如此,fun方法将被hystrix代理,如果代理中出错,会调用 fallbackMethod 设置的方法 gun。
eureka 的使用
创建一个空项目,新建一个 有 main方法的启动类。在启动类上注解EnableEurekaServer 如下:
@EnableEurekaServer
@EnableAutoConfiguration
public class EurekaServerApplication {
public static void main(String[] args) {
SpringApplication.run(EurekaServerApplication.class, args);
}
}
然后在/config目录下创建文件 application.properties文件如下:
server.port=3333
eureka.instance.hostname=localhost
#不要向注册中心注册自己
eureka.client.register-with-eureka=false
eureka.instance.prefer-ip-address=true
#禁止检索服务
eureka.client.fetch-registry=false
eureka.client.service-url.defaultZone=http://${eureka.instance.hostname}:${server.port}/eureka
启动后,即可通过地址访问eureka 的控制面板了: http://localhost:3333/
服务提供者
然后就是eureka 客户端(服务提供者) 的注册。
新建项目,pom文件如下:
<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>provider1</groupId>
<artifactId>product1</artifactId>
<version>0.0.1-SNAPSHOT</version>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.3.RELEASE</version>
</parent>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Finchley.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>
spring-cloud-starter-netflix-eureka-client
</artifactId>
<version>2.0.0.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>5.0.7.RELEASE</version>
</dependency>
</dependencies>
</project>
然后新建application.yml文件
server:
port: 9895
spring:
application:
name: product1
eureka:
client:
serviceUrl:
defaultZone: http://localhost:3333/eureka/
instance:
preferIpAddress: true
instance-id: ${spring.cloud.client.ip-address}:${server.port} # 这样配置,可以让eureka中显示的instance上的连接是ip形式。而非域名形式
hostname: ${spring.cloud.client.ip-address} #这样在eureka中显示时,就是ip了。
然后创建 启动类,给启动类 注解 @SpringBootApplication ,即可。
然后在eureka 中可以看到有服务提供者。
服务的消费者
新建项目,新建spring启动类,在类上注解
@SpringBootApplication
这个注解。
1、然后在 /config 下面创建 application.yml 文件。如下内容
eureka:
client:
serviceUrl:
defaultZone: http://localhost:3333/eureka/
register-with-eureka: false # 表示不让 eureka 发现自己,因为咱只是用eureka发现服务而已,并不提供服务。
2、并且在pom中加入依赖:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
如此,项目即可连接上eureka服务端。
然后可在某类中注入:
@Autowired
private LoadBalancerClient client;
然后即可使用 client对象获取 在 eureka 中注册的服务了。
如:
ServiceInstance instance = client.choose("serviceId");
System.out.println(String.format("instance[%s,%s,%s,%s]",instance.getHost(),instance.getPort(),instance.getScheme(),instance.getUri()));
---这就是最简单的eureka消费者的配置了,就上面1、2 两步。
gateway的使用
最简单配置
创建一个工程
1.在pom中引入包:
<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.kangzye</groupId>
<artifactId>gateway1</artifactId>
<version>0.0.1-SNAPSHOT</version>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.3.RELEASE</version>
</parent>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Finchley.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</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-eureka-client
</artifactId>
</dependency>
</dependencies>
</project>
2。 在config下创建 application.yml 配置文件:
server:
port: 5001
spring:
application:
name: gateway1
cloud:
gateway:
discovery:
locator:
enabled: true
eureka:
client:
serviceUrl:
defaultZone: http://localhost:3333/eureka/
gateway会自动周期性从eureka获取提供者的信息。在默认配置下,启动一台提供者,在gateway上被发现的时间间隔测试大概为1分钟。客户端发送到eureka的心跳默认间隔是30s(应该可以通过配置来降低此时间)
3. 创建一个启动类,添加注解 @SpringBootApplication 启动即可。
如此完成了 gateway 的最简单的配置,该配置是将 在eureka 中注册的服务,通过 gateway 的地址和端口暴露出去。
比如如果有一个 serviceId 是 PROVIDE1 有path(/double?s=abc)可访问,那么使用地址(http://localhost:5001/PROVIDE1/double?s=abc) 即可访问到该 Controller 的方法中。
Feign 的使用
feign作为spring cloud的一个组件,用途在于封装rest风格的请求,让我们可以直接调用接口,而不是去自己封装 http 请求。而且返回结果也是自动封装成了对象。很方便。其实关键还在于,feign 提供了很多的其他支持,比如 ribbon 和 hystrix 。
a. 先讲 基本使用
需要引入的pom依赖:
spring-cloud-starter-netflix-ribbon:2.0.0.RELEASE
spring-web
spring-cloud-start-netflix-eureka-client
spring-cloud-start-feign:1.4.4.RELEASE
feign接口类如下:
@FeignClient(value = "PRODUCT1")
public interface FunService {
@RequestMapping("/fun")
public String abc(@RequestParam("s") String s);
}
1. 其中,@FeignClient(value="PRODUCT1") 有了这个注解在 接口上,实现是自动由框架完成的。value 的值,是在eureka 中注册的 提供者的 id 。
2. abc方法名可以是任意的,但是其上面的 RequestMapping 内的路径是必须和 提供者提供的 服务的路径是一致的。
3. @RquestParam("s") 也是必不可少的,s 是提供者的业务方法中定义的参数形参名字。需要保持一致。
在启动类上,需要添加上 @EnableFeignClients 注解,然后 被FeignClient 注解的service接口才会被自动实现成 Bean对象。
之后就可以在业务中通过 @Autowired 注入并使用了:
public class Client2 {
@Autowired
FunService funService;
public void fun() {
Flux<Long> interval = Flux.interval(Duration.of(1, ChronoUnit.SECONDS));
interval.subscribe(o->{
System.out.println(funService.abc("i."+o));
});
}
}
上面使用了 reactor框架的 flux 。代码意思就是 每隔1秒,就发生一个型号,在信号发生之后,就调用 服务,并打印出来。
我测试时使用了 3个 提供者。每个提供者返回的结果都有自己特定的标识。观察所见,feign 自动是使用 ribbon 负载均衡的(轮询方式默认),并且是使用了hystrix进行容错。
b. 再讲如何配合ribbon和 hystrix