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文件如下:
4.0.0 provider1 product1 0.0.1-SNAPSHOT org.springframework.boot spring-boot-starter-parent 2.0.3.RELEASE org.springframework.cloud spring-cloud-dependencies Finchley.RELEASE pom import org.springframework.cloud spring-cloud-starter-netflix-eureka-client 2.0.0.RELEASE org.springframework spring-web 5.0.7.RELEASE
然后新建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中加入依赖:
org.springframework.cloud spring-cloud-starter-netflix-eureka-client
如此,项目即可连接上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中引入包:
4.0.0 com.kangzye gateway1 0.0.1-SNAPSHOT org.springframework.boot spring-boot-starter-parent 2.0.3.RELEASE org.springframework.cloud spring-cloud-dependencies Finchley.RELEASE pom import org.springframework.cloud spring-cloud-starter-gateway org.springframework.boot spring-boot-starter-actuator org.springframework.cloud spring-cloud-starter-netflix-eureka-client
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() { Fluxinterval = 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