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