springcloud

springcloud

springcloud eureka

Eureka 介绍

Eureka主要由两个组件组成:Eureka服务器和Eureka客户端。 Eureka服务器用作服务注册服务器。 Eureka客户端是一个java客户端,用来简化与服务器的交互、作为轮询负载均衡器,并提供服务的故障切换支持。

demo

pom文件

<dependency>
 <groupId>org.springframework.cloud</groupId>
 <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
 </dependency>

配置文件

server:
  port: 8801

spring:
  application:
    name:eureka-server

eureka:
  instance:
    hostname: localhost
  client:
    registerWithEureka: false
    fetchRegistry: false
    serviceUrl:
      defaultZone: http://192.168.1.154:8801/eureka/
  • spring.application.name: 这个是指定服务名称。
  • server.port:服务指定的端口。
  • eureka.client.register-with-eureka:表示是否将自己注册到Eureka Server,默认是true。
  • eureka.client.fetch-registry:表示是否从Eureka Server获取注册信息,默认为true。
  • eureka.client.serviceUrl.defaultZone: 这个是设置与Eureka Server交互的地址,客户端的查询服务和注册服务都需要依赖这个地址。

启动类

在服务端这边只需要在SpringBoot启动类添加@EnableEurekaServer注解就可以了,该注解表示此服务是一个服务注册中心服务

package com.eureka;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;

@SpringBootApplication
@EnableEurekaServer
public class EurekaApplication {
    public static void main(String[] args) {
        SpringApplication.run(EurekaApplication.class, args);
    }
}

Eureka高可用

单点服务注册中心生产环境中就显得不适合,显然这并不适合应用于线上生产环境。作为分布式系统最重要的注册服务功能,为了使其高可用,使用集群是最普遍的方式。Eureka可以通过互相注册的方式来实现高可用的部署。

Eureka实现相互注册的方式很简单,只需要将各个服务端的地址相互进行配置即可

高可用创建

创建两个或多个相同的单点服务注册项目。只需要修改项目的配置信息即可

多个服务项目注册

server2配置信息:

spring.application.name=springcloud-eureka-server
server.port=8002
# 服务地址别名
eureka.instance.hostname = server2
## 这里设置另一个Eureka Server交互的地址,如果是多个就通过 ","逗号隔开,如果是超过三个服务中心这里就其余两个
eureka.client.serviceUrl.defaultZone=http://server3:8003/eureka/

server3配置信息:

spring.application.name=springcloud-eureka-server
server.port=8003
# 服务地址别名
eureka.instance.hostname = server3
## 这里设置另一个Eureka Server交互的地址,如果是多个就通过 ","逗号隔开
eureka.client.serviceUrl.defaultZone=http://server2:8002/eureka/

上述的配置在之前已经说过了,这里就不在过多描述了。这里的服务端配置和之前项目的服务端配置略有不同,允许自己进行注册了。并且这里的eureka.instance.hostname相当于是对服务地址起一个别名,也可以不配置,默认将会使用IP进行查找。eureka.client.serviceUrl.defaultZone这里配置的是另一个服务端的地址,如果是多个就通过 ","逗号隔开。

因为这里使用了别名进行区分服务,所以需要在hosts文件添加如下配置,用于做映射。

127.0.0.1     server2
127.0.0.1     server3

hosts文件地址:

Windows 系统地址:C:\Windows\System32\drivers\etc\hosts

Linux系统地址: /etc/hosts

配置完成之后,启动这两个服务,然后在浏览器输入:
http://server2:8002/

http://server3:8003/

springcloud config

config介绍

Spring Cloud Config项目是一个解决分布式系统的配置管理方案。它包含了Client和Server两个部分,server提供配置文件的存储、以接口的形式将配置文件的内容提供出去,client通过接口获取数据、并依据此数据初始化自己的应用。

demo

config server

配置中心服务端

pom
<dependency>
  <groupId>org.springframework.cloud</groupId>
  <artifactId>spring-cloud-config-server</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
配置文件
spring:
  profiles:
    active: git
  application:
    name: spring-cloud-config
  cloud:
    config:
      server:
        git:
          uri: https://gitee.com/zhujiayu80/springcloud-config
          username: zhujiayu80@163.com
          password: zjy159357
server:
  port: 8903
eureka:
  client:
    serviceUrl:
      defaultZone: http://192.168.1.154:8801/eureka/

配置说明:

  • spring.application.name: 这个是指定服务名称。
  • server.port:服务指定的端口。
  • eureka.client.serviceUrl.defaultZone: 这个是设置与Eureka Server交互的地址,客户端的查询服务和注册服务都需要依赖这个地址。
  • spring.cloud.config.server.git.uri: 配置的Git长裤的地址。
  • spring.cloud.config.server.git.search-paths: git仓库地址下的相对地址 多个用逗号","分割。
  • spring.cloud.config.server.git.username:git仓库的账号。
  • spring.cloud.config.server.git.password:git仓库的密码。

注:如果想使用本地方式读取配置信息,那么只需将spring.cloud.config.server.git的配置改成spring.profiles.active=native,然后在resources路径下新增一个文件即可。

启动类

代码这块也很简单,在程序主类中,额外添加@EnableConfigServer注解,该注解表示启用config配置中心功能。代码如下:

package com.springcloudconfig.config;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.config.server.EnableConfigServer;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;

@SpringBootApplication
@EnableConfigServer
@EnableEurekaClient
public class ConfigApplication {
    public static void main(String[] args) {
        SpringApplication.run(ConfigApplication.class, args);
    }
}

config client

配置中心客户端

pom
 <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-config</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-config-client</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>
配置信息
spring.cloud.config.name=feign-consumer
spring.cloud.config.profile=test
spring.cloud.config.label=master
spring.cloud.config.discovery.enabled=true
spring.cloud.config.discovery.serviceId=spring-cloud-config
eureka.client.serviceUrl.defaultZone=http://192.168.1.154:8801/eureka/

配置说明:

  • spring.cloud.config.name: 获取配置文件的名称。
  • spring.cloud.config.profile: 获取配置的策略。
  • spring.cloud.config.label:获取配置文件的分支,默认是master。如果是是本地获取的话,则无用。
  • spring.cloud.config.discovery.enabled: 开启配置信息发现。
  • spring.cloud.config.discovery.serviceId: 指定配置中心的service-id,便于扩展为高可用配置集群。
  • eureka.client.serviceUrl.defaultZone: 这个是设置与Eureka Server交互的地址,客户端的查询服务和注册服务都需要依赖这个地址。

:上面这些与spring-cloud相关的属性必须配置在bootstrap.properties中,config部分内容才能被正确加载。因为bootstrap.properties的相关配置会先于application.properties,而bootstrap.properties的加载也是先于application.properties。需要注意的是eureka.client.serviceUrl.defaultZone要配置在bootstrap.properties,不然客户端是无法获取配置中心参数的,会启动失败! 、

application.properties配置

spring.application.name=springcloud-config-client
server.port=9006

配置说明:

  • spring.application.name: 这个是指定服务名称。
  • server.port:服务指定的端口。
启动类
package com.cloud.feign.feign;

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.context.annotation.Bean;
import org.springframework.web.client.RestTemplate;

@SpringBootApplication
@EnableEurekaClient
public class FeignApplication {
    public static void main(String[] args) {
        SpringApplication.run(FeignApplication.class, args);
    }
}
controller

为了方便查询,在控制中进行参数的获取,并返回。@Value注解是默认是从application.properties配置文件获取参数,但是这里我们在客户端并没有进行配置,该配置在配置中心服务端,我们只需指定好了配置文件之后即可进行使用

package com.cloud.feign.feign.api;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * @author: ZJY
 * @Date: 2020/4/30 9:26
 */
@RestController
@RequestMapping
public class GetHelloController {

    @Value("${name}")
    private String name;

    @GetMapping("/getBootstrap")
    public String getBootstrap(){
          return name;
    }
}

git服务器配置文件

feign-consumer-dev.yml

文件内容:name:hello

测试

依次启动项目:eureka、config、client 。调用接口localhost:9006/getBootstrap

常见问题

1.如果出现直接访问config server可行。但是通过config client获取git服务器中的配置信息报错。要查看client中配置的文件名是否正确,或者等几分钟重新启动client。因为获取server中的配置信息需要时间。

Feign服务消费者和负载均衡Ribbon

SpringCloud Feign

Feign 介绍

Feign是一个声明式的Web Service客户端,它使得编写Web Serivce客户端变得更加简单。我们只需要使用Feign来创建一个接口并用注解来配置它既可完成。它具备可插拔的注解支持,包括Feign注解和JAX-RS注解。Feign也支持可插拔的编码器和解码器。Spring Cloud为Feign增加了对Spring MVC注解的支持,还整合了Ribbon和Eureka来提供均衡负载的HTTP客户端实现。

dome

pom文件
      <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
        </dependency>
feign客户端

这里我们定义两个消费者,springcloud-feign-consumerspringcloud-feign-consumer1,一个使用feign做转发,另一个为一个普通的项目。 添加如上的依赖之后,在application.properties`添加如下的配置:

consumer配置信息

bootstrap.properties 基于config远程配置

eureka.client.serviceUrl.defaultZone=http://192.168.1.154:8801/eureka/
spring.cloud.config.name=feign-consumer
spring.cloud.config.profile=dev
spring.cloud.config.label=master
spring.cloud.config.discovery.enabled=true
spring.cloud.config.discovery.serviceId=spring-cloud-config

application.proterties

spring.application.name=springcloud-feign-consumer
server.port=8802
consumer1配置信息

bootstrap.properties 基于config远程配置

eureka.client.serviceUrl.defaultZone=http://192.168.1.154:8801/eureka/
spring.cloud.config.name=feign-consumer
spring.cloud.config.profile=dev
spring.cloud.config.label=master
spring.cloud.config.discovery.enabled=true
spring.cloud.config.discovery.serviceId=spring-cloud-config

application.proterties

#consumer根据该名称远程调用consumer1中的功能
spring.application.name=springcloud-feign-consumer1
server.port=8802

配置说明:

  • spring.application.name: 这个是客户端的服务名称。如果有多个服务使用同一个名称但是访问地址不同,结合ribbon 使用,则可以实现负载均衡功能。
  • server.port:服务指定的端口。
  • eureka.client.serviceUrl.defaultZone: 注册中心服务端的地址
启动类
@SpringBootApplication
@EnableEurekaClient
@EnableFeignClients
public class FeignApplication {
    public static void main(String[] args) {
        SpringApplication.run(FeignApplication.class, args);
    }
}

需要定义转发的服务,这里使用@FeignClient注解来实现,该注解表示需要转发服务的名称,该名称在application.properties中进行配置。 这里我们把请求转发到第二个服务 springcloud-feign-consumer1。即通过consume调用consumer1中的功能。

consumer中转发类接口
@FeignClient(value = "springcloud-feign-consumer1")
public interface SayHello {
    @RequestMapping(value = "hello",method = RequestMethod.GET)
    public String getHello();
}
service类
@Service
public class HelloService {
    @Autowired
    private SayHello sayHello;
    
    public String getHello(String name){
        return sayHello.getHello();
    }
}
controller类
@RestController
@RequestMapping
public class GetHelloController {

    @Autowired
    HelloService helloService;

    @Value("${name}")
    private String name;
    
    @GetMapping("/getHello")
    public String getHello(String name){
        String hello = helloService.getHello(name);
        return hello;
    }
    
    @GetMapping("/getBootstrap")
    public String getBootstrap(){
          return name;
    }
}
consumer1启动类
@SpringBootApplication
	@EnableDiscoveryClient
	public class FeignConsumerApplication2 {
		public static void main(String[] args) {
			SpringApplication.run(FeignConsumerApplication2.class, args);
			  System.out.println("feign第二个消费者服务启动...");
		}
	}
controller1类
@RestController
	public class ConsumerController {
		@RequestMapping("/hello")
	    public String index(@RequestParam String name) {
	        return name+",Hello World";
	    }
	}
测试

可以通过访问http://localhost:8802/getHello?name=test调用controller1中的接口“/hello”返回“test,Hello World”。

springcloud ribbon

ribbon介绍

Ribbon是Netflix发布的开源项目,主要功能是提供客户端的软件负载均衡算法,将Netflix的中间层服务连接在一起。Ribbon客户端组件提供一系列完善的配置项如连接超时,重试等。简单的说,就是在配置文件中列出Load Balancer后面所有的机器,Ribbon会自动的帮助你基于某种规则(如简单轮询,随即连接等)去连接这些机器。我们也很容易使用Ribbon实现自定义的负载均衡算法。简单地说,Ribbon是一个客户端负载均衡器。 

demo

pom
<dependency>
     <groupId>org.springframework.cloud</groupId>
     <artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
</dependency>
<dependency>
      <groupId>org.springframework.cloud</groupId>
      <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<dependency>
       <groupId>org.springframework.cloud</groupId>
       <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>

客户端

这里我们定义三个服务,一个服务使用Ribbon做负载均衡,另外两个做普通的服务,服务名称依次为springcloud-ribbon-consumerspringcloud-ribbon-consumer2springcloud-ribbon-consumer3。 添加如上的依赖之后,在application.properties添加如下的配置:

consumer 配置信息:

spring.application.name=springcloud-ribbon-consumer
server.port=9006
eureka.client.serviceUrl.defaultZone=http://localhost:8003/eureka/

consumer2 配置信息:

spring.application.name=springcloud-ribbon-consumer2
server.port=9007
eureka.client.serviceUrl.defaultZone=http://localhost:8003/eureka/

consumer3 配置信息:

这里的服务名称和另一个服务的名称保持一致才能实现负载均衡功能。

spring.application.name=springcloud-ribbon-consumer2
server.port=9008
eureka.client.serviceUrl.defaultZone=http://localhost:8003/eureka/

配置说明:

  • spring.application.name: 这个是客户端的服务名称。如果有多个服务使用同一个名称但是访问地址不同,结合ribbon 使用,则可以实现负载均衡功能。
  • server.port:服务指定的端口。
  • eureka.client.serviceUrl.defaultZone: 注册中心服务端的地址。
springcloud-ribbon-consumer

使用Ribbon实现负载均衡,只需要在启动类中实例化RestTemplate,通过@LoadBalanced注解开启均衡负载能力.。

启动类

	@SpringBootApplication
	@EnableDiscoveryClient
	public class RibbonConsumerApplication {
		public static void main(String[] args) {
			SpringApplication.run(RibbonConsumerApplication.class, args);
			System.out.println("ribbon第一个消费者服务启动...");
		}
	
		@Bean
		@LoadBalanced
		public RestTemplate restTemplate() {
			return new RestTemplate();
		}
	}

需要定义转发的服务,这里使用RestTemplate来进行调用,调用另外一个服务的名称

转发类controller
@RestController
	public class ConsumerController {
	   
	    @Autowired
	    RestTemplate restTemplate;
	    
	    @RequestMapping("/hello")
	    public String hello() {
	    	//进行远程调用
	        return restTemplate.getForObject("http://springcloud-ribbon-consumer2/hello/?name=xuwujing", String.class);
	    }
	}

springcloud-ribbon-consumer2springcloud-ribbon-consumer3代码基本和fegin中的springcloud-feign-consumer一样,因此这里就不在贴代码了。

测试

http://localhost:9006//hello

然后进行重复访问,返回如下结果:

xuwujing,Hello World!
xuwujing,Hello World! 这是另一个服务!
xuwujing,Hello World!
xuwujing,Hello World! 这是另一个服务!
xuwujing,Hello World!
xuwujing,Hello World! 这是另一个服务!

说明已经实现了负载均衡功能了。 通过consume访问consumer2和consumer3.

我们从上述的结果中发现了一点,这个调用貌似是有规律的,两个服务进行来回调用。那么根据这个我们发现了,负载均衡是由策略的。上述的这个示例的策略就是其中的一个RoundRobinRule轮询策略。

这里就顺便说下Ribbon的策略,Ribbon一共有7中策略,默认使用的策略是轮询。策略说明如下表格:

策略名 策略声明 策略描述 实现说明
BestAvailableRule public class BestAvailableRule extends ClientConfigEnabledRoundRobinRule 选择一个最小的并发请求的server 逐个考察Server,如果Server被tripped了,则忽略,在选择其中ActiveRequestsCount最小的server
AvailabilityFilteringRule public class AvailabilityFilteringRule extends PredicateBasedRule 过滤掉那些因为一直连接失败的被标记为circuit tripped的后端server,并过滤掉那些高并发的的后端server(active connections 超过配置的阈值) 使用一个AvailabilityPredicate来包含过滤server的逻辑,其实就就是检查status里记录的各个server的运行状态
WeightedResponseTimeRule public class WeightedResponseTimeRule extends RoundRobinRule 根据响应时间分配一个weight,响应时间越长,weight越小,被选中的可能性越低。 一个后台线程定期的从status里面读取评价响应时间,为每个server计算一个weight。Weight的计算也比较简单responsetime 减去每个server自己平均的responsetime是server的权重。当刚开始运行,没有形成status时,使用roubine策略选择server。
RetryRule public class RetryRule extends AbstractLoadBalancerRule 对选定的负载均衡策略机上重试机制。 在一个配置时间段内当选择server不成功,则一直尝试使用subRule的方式选择一个可用的server
RoundRobinRule public class RoundRobinRule extends AbstractLoadBalancerRule roundRobin方式轮询选择server 轮询index,选择index对应位置的server
RandomRule public class RandomRule extends AbstractLoadBalancerRule 随机选择一个server 在index上随机,选择index对应位置的server
ZoneAvoidanceRule public class ZoneAvoidanceRule extends PredicateBasedRule 复合判断server所在区域的性能和server的可用性选择server 使用ZoneAvoidancePredicate和AvailabilityPredicate来判断是否选择某个server,前一个判断判定一个zone的运行性能是否可用,剔除不可用的zone(的所有server),AvailabilityPredicate用于过滤掉连接数过多的Server。

这里也顺便说明如何指定一个策略使用方法。

最简单的方式

application.properties添加如下配置:

springcloud-ribbon-consumer2.ribbon.NFLoadBalancerRuleClassName=com.netflix.loadbalancer.RandomRule

该配置的意思是为springcloud-ribbon-consumer2服务指定随机策略。

另一种方式

新建一个类,通过@Bean注解指定策略。

	@Configuration
	public class RibbonConfiguration{
	      @Bean
	      public IRule ribbonRule(){        
	          return new RandomRule();
	     }
	}

然后再通过@RibbonClien注解指定服务。

	@RibbonClient(name="springcloud-ribbon-consumer2", configuration=RibbonConfiguration.class)
	public class HelloRibbon{	 
	}

注: 如果有的服务没有在Eureka进行注册,可以使用ribbon.listOfServers方式在配置文件中来指定服务。

例如:

springcloud-ribbon-consumer2.ribbon.listOfServers:localhost:9007,localhost:9008

添加好了该配置之后,我们重启springcloud-ribbon-consumer服务,然后依旧重复访问 http://localhost:9006//hello 该地址,
访问的结果如下:

xuwujing,Hello World!
xuwujing,Hello World! 这是另一个服务!
xuwujing,Hello World! 这是另一个服务!
xuwujing,Hello World!
xuwujing,Hello World!
xuwujing,Hello World!

可以看到已经成功实现了随机访问的策略!

springcloud feign结合ribbon实现负载均衡

Fegin包含了Ribbon,可以直接实现负载均衡功能。这里我们就在Ribbon的项目稍微进行改造下实现该功能。

首先在pom文件添加Fegin的依赖包。

	<dependency>
		<groupId>org.springframework.cloud</groupId>
		<artifactId>spring-cloud-starter-openfeign</artifactId>
	</dependency>

然后在springcloud-ribbon-consumer项目的启动类上添加@EnableFeignClients注解,启用feign进行远程调用。

添加完成之后,新建一个类,实现feign远程调用。
代码如下:

	@FeignClient(name= "springcloud-ribbon-consumer2") 
	public interface HelloRemote {
	    @RequestMapping(value = "/hello")
	    public String hello(@RequestParam(value = "name") String name);
	}

最后在提供一个新的接口供外部调用。这里就直接在之前的代码上新加一个接口了。
代码如下:

	@RestController
	public class ConsumerController {
	   
	    @Autowired
	    RestTemplate restTemplate;
	    
	    @RequestMapping("/hello")
	    public String hello() {
	        return restTemplate.getForObject("http://springcloud-ribbon-consumer2/hello/?name=xuwujing", String.class);
	    }
	    
	   
	    @Autowired
	    HelloRemote helloRemote;
		
	    @RequestMapping("/hello/{name}")
	    public String index(@PathVariable("name") String name) {
	    	System.out.println("接受到请求参数:"+name+",进行转发到其他服务!");
	        return helloRemote.hello(name);
	    }
	}

添加完之后,重启springcloud-ribbon-consumer服务,然后依旧重复访问 http://localhost:9006//hello/pancm 该地址,
访问的结果如下:

pancm,Hello World!
pancm,Hello World! 这是另一个服务!
pancm,Hello World!
pancm,Hello World! 这是另一个服务!
pancm,Hello World!
pancm,Hello World! 这是另一个服务!

Hystrix断路器和Dashboard断路器监控

SpringCloud Hystrix

Hystrix介绍

Netflix创建了一个名为Hystrix的库,它实现了断路器模式。主要的目的是为了解决服务雪崩效应的一个组件,是保护服务高可用的最后一道防线。

demo

pom文件
<dependency>
		<groupId>org.springframework.cloud</groupId>
		<artifactId>spring-cloud-starter-openfeign</artifactId>
	</dependency>
	<dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
    </dependency>

注: 实际上这里是不需要Hystrix依赖的,Fegin已经添加了Hystrix依赖。

客户端

这里我们把之前的springcloud-fegin-consumer项目稍微改造下,项目名改为springcloud-hystrix-consumer。然后在application.properties配置文件新增如下配置, feign.hystrix.enabled配置表示是否启用熔断机制。

feign.hystrix.enabled=true

增加了配置之后,我们在来把之前的fegin进行定义转发服务的@FeignClient注解进行添加一个回调方法fallback。代码改造后的实现如下:

@FeignClient(value = "ribbon-provice",fallback = SayHelloImp.class)
public interface SayHello {
    @RequestMapping(value = "hello",method = RequestMethod.GET)
    public String getHello();
}

新增一个回调类SayHelloImp,用于处理断路的情况

@Component
public class SayHelloImp implements SayHello {
    @Override
    public String getHello() {
        return "调用失败!";
    }
}
断路情况另一种处理方法

在方法上添加回调方法

 @HystrixCommand(fallbackMethod = "getHello")
    public String sayHello(String name){
        return restTemplate.getForObject("http://ribbon-provice/hello" + name,String.class);
    }
测试

完成如上的工程开发之后,我们依次启动服务端和客户端的

SpringCloud Hystrix-Dashboard

Hystrix-Dashboard 介绍

Hystrix-dashboard是一款针对Hystrix进行实时监控的工具,通过Hystrix Dashboard我们可以在直观地看到各Hystrix Command的请求响应时间, 请求成功率等数据。

demo

pom文件
<dependency>
		<groupId>org.springframework.cloud</groupId>
		<artifactId>spring-cloud-starter-openfeign</artifactId>
	</dependency>
	
	<dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
    </dependency>
	   <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-netflix-hystrix-dashboard</artifactId>
    </dependency>
<dependency>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-actuator</artifactId>
	</dependency>
启动类

在启动类上添加

  • EnableCircuitBreaker:表示启用hystrix功能。
  • EnableHystrixDashboard:启用 HystrixDashboard 断路器看板 相关配置。
@SpringBootApplication
	@EnableDiscoveryClient
	@EnableHystrixDashboard
	@EnableCircuitBreaker
	@EnableFeignClients
	public class HystrixDashboardApplication {
		public static void main(String[] args) {
			SpringApplication.run(HystrixDashboardApplication.class, args);
			  System.out.println("hystrix dashboard 服务启动...");
		}
	}

然后在到application.properties配置文件中新增如下配置:

	management.endpoints.web.exposure.include=hystrix.stream
	management.endpoints.web.base-path=/

该配置的意思是指定hystrixDashboard的访问路径,SpringBoot2.x以上必须指定,不然是无法进行访问的,访问会出现 Unable to connect to Command Metric Stream 错误。

如果不想使用配置的话,也可以使用代码进行实现。
实现的代码如下:

	@Component
	public class HystrixServlet extends Servlet{
	
		@Bean
	    public ServletRegistrationBean getServlet() {
	        HystrixMetricsStreamServlet streamServlet = new HystrixMetricsStreamServlet();
	        ServletRegistrationBean registrationBean = new ServletRegistrationBean(streamServlet);
	        registrationBean.setLoadOnStartup(1);
	        registrationBean.addUrlMappings("/hystrix.stream");
	        registrationBean.setName("HystrixMetricsStreamServlet");
	        return registrationBean;
	    }	
	}

功能测试

完成如上的工程改造之后,我们启动该程序。
然后在浏览器输入:

http://localhost:9010/hystrix

会出现以下的界面:

在这里插入图片描述

可以通过该界面监控使用了hystrix dashboard的项目。这里我们依照提示在中间的输入框输入如下的地址:

http://localhost:9010/hystrix.stream

会出现以下的界面:

img

该界面就是Hystrix Dashboard监控的界面了,通过这个界面我们可以很详细的看到程序的信息。关于这些信息中说明可以用网上找到的一张来加以说明。

img

: 如果界面一直提示loading,那么是因为没有进行请求访问,只需在到浏览器上输入:http://localhost:9010/hello/pancm,然后刷新该界面就可以进行查看了。

SpringCloud Zuul

介绍

Spring Cloud Zuul 主要的功能是提供负载均衡、反向代理、权限认证、动态路由、监控、弹性、安全等的边缘服务。其主要作用是为微服务架构提供了前门保护的作用,同时将权限控制这些较重的非业务逻辑内容迁移到服务路由层面,使得服务集群主体能够具备更高的可复用性和可测试性。

demo

zuul服务

注册中心服务配置完成之后,我们在新增一个Zuul服务,该服务的名称为springcloud-zuul-gateway,该服务的 pom配置、application.properties配置和代码如下:

pom:

<dependencies>
	<dependency>
		<groupId>org.springframework.cloud</groupId>
		<artifactId>spring-cloud-starter</artifactId>
	</dependency>
	<dependency>
		<groupId>org.springframework.cloud</groupId>
		<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
	</dependency>	
	<dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-netflix-zuul</artifactId>
    </dependency>
</dependencies>

application.properties:

spring.application.name=springcloud-zuul-gateway
server.port = 9009
eureka.client.serviceUrl.defaultZone=http://localhost:8006/eureka/
zuul.routes.hello.path = /hello/**
zuul.routes.hello.url = http://localhost:9010/hello
zuul.routes.hi.path = /hi/**
zuul.routes.hi.url = http://localhost:9011/hi

配置说明:

  • spring.application.name: 这个是指定服务名称。
  • server.port:服务指定的端口。
  • eureka.client.serviceUrl.defaultZone: 这个是设置与Eureka Server交互的地址,客户端的查询服务和注册服务都需要依赖这个地址。
  • zuul.routes.{route}.path:自定义路由的规则,通过path配置路径进行过滤;
  • zuul.routes.{route}.url: 自定义路由的规则,访问上述的路径会转发到该配置的地址;

注:上述的zuul.routes.{route}.pathzuul.routes.{route}.url一般来说是作为传统的方式进行配置,是不依赖于Eureka,是属于一对一的配置。例如,访问:http://localhost:9009/hello/pancm 的话就会跳转到http://localhost:9010/hello/pancm 地址上。

代码:

@SpringBootApplication
@EnableDiscoveryClient
@EnableZuulProxy   
public class ZuulApplication {
	public static void main(String[] args) {
		SpringApplication.run(ZuulApplication.class, args);
		 System.out.println("zuul 服务启动...");
	}
}

客户端

这里我们也需要创建两个客户端服务,来进行验证Zuul路由网关是否生效。
创建两个客户端服务,名称分别为springcloud-zuul-server1springcloud-zuul-server2,两个pom文件的配置如下:

 <dependencies>
	<dependency>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-web</artifactId>
	</dependency>
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
    </dependency>
</dependencies>

两个application.properties配置文件也基本相同,除了名称和端口不一致。

springcloud-zuul-server1application.properties配置:

spring.application.name=springcloud-zuul-server1
server.port=9010
eureka.client.serviceUrl.defaultZone=http://localhost:8801/eureka/

springcloud-zuul-server2application.properties配置:

spring.application.name=springcloud-zuul-server2
server.port=9011
eureka.client.serviceUrl.defaultZone=http://localhost:8801/eureka/

springcloud-zuul-server1服务的代码:

主类

@SpringBootApplication
@EnableEurekaClient
@EnableFeignClients
@EnableHystrix
public class FeignApplication {

    public static void main(String[] args) {
        SpringApplication.run(FeignApplication.class, args);
    }
    
    @Bean
    @LoadBalanced
    RestTemplate restTemplate(){
        return new RestTemplate();
    }
}

控制层:

@RestController
@RequestMapping("/hello")
public class GetHelloController {

    @Autowired
    HelloService helloService;

    @Value("${name}")
    private String name;
    @GetMapping("/getHello")
    public String getHello(){
        String hello = helloService.getHello();
        return hello;
    }

    @GetMapping("/sayHello")
    public String sayHello(String string){
        String s = helloService.sayHello(string);
        return s;
    }

    @GetMapping("/getBootstrap")
    public String getBootstrap(){
          return name;
    }

}

}

`springcloud-provice服务的代码:

主类

@SpringBootApplication
@EnableEurekaClient
public class ProviceApplication {
    public static void main(String[] args) {
        SpringApplication.run(ProviceApplication.class, args);
    }
}

控制层:

@RequestMapping("/test")
public class HelloController {

    @GetMapping("/test")
    public String test(){
        System.out.println("ceshi");
        return "test,你好!";
    }
    
    @GetMapping("/hello")
    public String getHello(){
        return "hello !";
    }
}

注:这里故意将两个服务的接口参数请求和返回值弄成不一样,以便对Zull的功能进行多方面测试。

测试

完成上述的代码开发后,我们来进行测试springcloud-zuul是否可以地址过滤转发功能。
首先依次启动springcloud-zuul-eurekaspringcloud-zuul-gatewayspringcloud-zuul-server1springcloud-zuul-server2这四个项目。其中9009是服务springcloud-zuul-gateway的端口,9010是第一个客户端springcloud-zuul-server1的端口,9011是第二个客户端springcloud-zuul-server2的端口。
启动成功之后,在浏览器输入:

<http://localhost:8802/hello/getHello

界面返回:

hello

在浏览器输入:

<http://localhost:8804/test/hello

界面返回:

hello !

可以看出程序正常启动,并且客户端的接口返回正确!
那么我们再来使用同样路径来访问zuul,因为是在本地进行测试,因此只需要更改下端口就可以了,将上述在浏览器访问的地址的端口自都改成9009。

@SpringBootApplication
@EnableEurekaClient
public class ProviceApplication {
    public static void main(String[] args) {
        SpringApplication.run(ProviceApplication.class, args);
    }
}

控制层:

@RequestMapping("/test")
public class HelloController {

    @GetMapping("/test")
    public String test(){
        System.out.println("ceshi");
        return "test,你好!";
    }
    
    @GetMapping("/hello")
    public String getHello(){
        return "hello !";
    }
}

注:这里故意将两个服务的接口参数请求和返回值弄成不一样,以便对Zull的功能进行多方面测试。

测试

完成上述的代码开发后,我们来进行测试springcloud-zuul是否可以地址过滤转发功能。
首先依次启动springcloud-zuul-eurekaspringcloud-zuul-gatewayspringcloud-zuul-server1springcloud-zuul-server2这四个项目。其中9009是服务springcloud-zuul-gateway的端口,9010是第一个客户端springcloud-zuul-server1的端口,9011是第二个客户端springcloud-zuul-server2的端口。
启动成功之后,在浏览器输入:

<http://localhost:8802/hello/getHello

界面返回:

hello

在浏览器输入:

<http://localhost:8804/test/hello

界面返回:

hello !

可以看出程序正常启动,并且客户端的接口返回正确!
那么我们再来使用同样路径来访问zuul,因为是在本地进行测试,因此只需要更改下端口就可以了,将上述在浏览器访问的地址的端口自都改成9009。

展开阅读全文

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 大白 设计师: CSDN官方博客
应支付0元
点击重新获取
扫码支付

支付成功即可阅读