Eureka是Netflix开源的一款提供服务注册和发现的产品,它提供了完整的Service Registry和Service Discovery实现。也是springcloud体系中最重要最核心的组件之一。
由于各种服务都注册到了服务中心,就有了去做很多高级功能条件。比如几台服务提供相同服务来做均衡负载;监控服务器调用成功率来做熔断,移除服务列表中的故障点;监控服务调用时间来对不同的服务器设置不同的权重等等。
Spring Cloud 封装了 Netflix 公司开发的 Eureka 模块来实现服务注册和发现。Eureka 采用了 C-S 的设计架构。Eureka Server 作为服务注册功能的服务器,它是服务注册中心。而系统中的其他微服务,使用 Eureka 的客户端连接到 Eureka Server,并维持心跳连接。这样系统的维护人员就可以通过 Eureka Server 来监控系统中各个微服务是否正常运行。Spring Cloud 的一些其他模块(比如Zuul)就可以通过 Eureka Server 来发现系统中的其他微服务,并执行相关的逻辑。
Eureka由两个组件组成:Eureka服务器和Eureka客户端。Eureka服务器用作服务注册服务器。Eureka客户端是一个java客户端,用来简化与服务器的交互、作为轮询负载均衡器,并提供服务的故障切换支持。Netflix在其生产环境中使用的是另外的客户端,它提供基于流量、资源利用率以及出错状态的加权负载均衡。
上图简要描述了Eureka的基本架构,由3个角色组成:
1、Eureka Server
提供服务注册和发现
2、Service Provider
服务提供方
将自身服务注册到Eureka,从而使服务消费方能够找到
3、Service Consumer
服务消费方
从Eureka获取注册服务列表,从而能够消费服务
服务中心自动提供了服务均衡负载的功能。
1、pom中添加依赖
org.springframework.cloud
spring-cloud-starter
org.springframework.cloud
spring-cloud-starter-eureka-server
org.springframework.boot
spring-boot-starter-test
test
2、启动类上添加@EnableEurekaServer注解
3、配置文件
eureka:
instance:
app-group-name: "用户权限服务"
appname: "用户权限服务"
prefer-ip-address: true
#健康心跳时间
lease-renewal-interval-in-seconds: 10
#最长剔除时间
lease-expiration-duration-in-seconds: 20
client:
registerWithEureka: true #是否向服务注册中心注册自己
fetchRegistry: true #是否检索服务
serviceUrl: #服务注册中心的配置内容,指定服务注册中心的位置,多个地址可使用 , 分隔。
defaultZone: http://eureka.xinhuamm.com:8080/eureka/
healthcheck:
enabled: false
在生产中我们可能需要三台或者大于三台的注册中心来保证服务的稳定性,配置的原理其实都一样,将注册中心分别指向其它的注册中心。这里只介绍三台集群的配置情况,其实和双节点的注册中心类似,每台注册中心分别又指向其它两个节点即可,使用application.yml来配置。
---
spring:
application:
name: spring-cloud-eureka
profiles: peer1
server:
port: 8000
eureka:
instance:
hostname: peer1
client:
serviceUrl:
defaultZone: http://peer2:8001/eureka/,http://peer3:8002/eureka/
---
spring:
application:
name: spring-cloud-eureka
profiles: peer2
server:
port: 8001
eureka:
instance:
hostname: peer2
client:
serviceUrl:
defaultZone: http://peer1:8000/eureka/,http://peer3:8002/eureka/
---
spring:
application:
name: spring-cloud-eureka
profiles: peer3
server:
port: 8002
eureka:
instance:
hostname: peer3
client:
serviceUrl:
defaultZone: http://peer1:8000/eureka/,http://peer2:8001/eureka/
1、如果安装过,首先卸载
$ sudo yum remove docker \
docker-client \
docker-client-latest \
docker-common \
docker-latest \
docker-latest-logrotate \
docker-logrotate \
docker-selinux \
docker-engine-selinux \
docker-engine
2、查看操作系统内核
uname -r
需要centos7版本
3、安装需要的包
第一步:
yum install -y yum-utils device-mapper-persistent-data lvm2
第二步:
官网地址
yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
##阿里云地址
yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
4、正式安装docker
yum install docker-ce
5、启动docker以及测试
systemctl start docker
docker run hello-world
ps: 跳过前面的,直接使用yum install docker-ce 也是可行的
1、启动时增加hosts
docker run -d --name test1 \
--add-host test1.a:1.2.3.4 \
local/test
2、docker-compose.yml文件指定
test2:
build: local/test
extra_hosts:
test1.a: 1.2.3.4
test1.b: 4.3.2.1
3、构建镜像时增加
test2:
build: local/test
extra_hosts:
test1.a: 1.2.3.4
test1.b: 4.3.2.1
ps: 容器启动后修改/etc/hosts,仅本次启动有效,重启就还原
1、将eureka客户端打成jar包,上传到服务器上 eureka-server-1.0.jar
2、创建Dockerfile
FROM openjdk:8
VOLUME /tmp
ADD eureka-server-1.0.jar app.jar
RUN bash -c 'touch /app.jar'
EXPOSE 8080
ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/app.jar"
3、创建deploy.sh 文件
#!/bin/bash
docker stop eureka-server
docker rm eureka-server
docker rmi eureka-server
docker build -t eureka-server .
docker run -d --name eureka-server -m 300M --memory-swap=300M -p 8080:8080 -it eureka-server
将feign层的接口抽出来,独立封装成一个项目,项目名叫dependence
1、pom文件依赖
org.springframework.cloud
spring-cloud-starter-netflix-eureka-client
org.springframework.cloud
spring-cloud-starter-openfeign
net.xinhuamm.noah
swagger-spring-boot-starter
org.springframework.cloud
spring-cloud-starter-sleuth
org.springframework.cloud
spring-cloud-sleuth-zipkin
2、创建接口的class文件
添加注解 @FeignClient(value = "application名字")
@FeignClient(value = "subscription")
public interface ISubscriptionService {
/**
* 获取某应用下的订阅号申请人信息
* @param appParam
* @return
*/
@PostMapping("/subscription/cms/listBaseInformation")
ResultModel> listBaseInformation(@RequestBody AppParam appParam);
}
3、打包发布到本地仓库
mvn clean deploy -DskipTests -pl dependence -am
服务调用与提供
在启动类上加上注解
@EnableEurekaClients
@EnableDiscoveryClient
熔断器的原理很简单,如同电力过载保护器。它可以实现快速失败,如果它在一段时间内侦测到许多类似的错误,会强迫其以后的多个调用快速失败,不再访问远程服务器,从而防止应用程序不断地尝试执行可能会失败的操作,使得应用程序继续执行而不用等待修正错误,或者浪费CPU时间去等到长时间的超时产生。熔断器也可以使应用程序能够诊断错误是否已经修正,如果已经修正,应用程序会再次尝试调用操作。
1.断路器机制
断路器很好理解, 当Hystrix Command请求后端服务失败数量超过一定比例(默认50%), 断路器会切换到开路状态(Open). 这时所有请求会直接失败而不会发送到后端服务. 断路器保持在开路状态一段时间后(默认5秒), 自动切换到半开路状态(HALF-OPEN). 这时会判断下一次请求的返回情况, 如果请求成功, 断路器切回闭路状态(CLOSED), 否则重新切换到开路状态(OPEN). Hystrix的断路器就像我们家庭电路中的保险丝, 一旦后端服务不可用, 断路器会直接切断请求链, 避免发送大量无效请求影响系统吞吐量, 并且断路器有自我检测并恢复的能力。
2.Fallback
Fallback相当于是降级操作. 对于查询操作, 我们可以实现一个fallback方法, 当请求后端服务出现异常的时候, 可以使用fallback方法返回的值. fallback方法的返回值一般是设置的默认值或者来自缓存.
3.资源隔离
在Hystrix中, 主要通过线程池来实现资源隔离. 通常在使用的时候我们会根据调用的远程服务划分出多个线程池. 例如调用产品服务的Command放入A线程池, 调用账户服务的Command放入B线程池. 这样做的主要优点是运行环境被隔离开了. 这样就算调用服务的代码存在bug或者由于其他原因导致自己所在线程池被耗尽时, 不会对系统的其他服务造成影响. 但是带来的代价就是维护多个线程池会对系统带来额外的性能开销. 如果是对性能有严格要求而且确信自己调用服务的客户端代码不会出问题的话, 可以使用Hystrix的信号模式(Semaphores)来隔离资源.
实际运用
1、配置文件
feign:
hystrix:
enabled: false
2、创建回调类
创建HelloRemoteHystrix类继承与HelloRemote实现回调的方法
@Component
public class HelloRemoteHystrix implements HelloRemote{
@Override
public String hello(@RequestParam(value = "name") String name) {
return "hello" +name+", this messge send failed ";
}
}
3、添加fallback属性
在HelloRemote类添加指定fallback类,在服务熔断的时候返回fallback类中的内容。
@FeignClient(name= "spring-cloud-producer",fallback = HelloRemoteHystrix.class)
public interface HelloRemote {
@RequestMapping(value = "/hello")
public String hello(@RequestParam(value = "name") String name);
}
Hystrix-dashboard是一款针对Hystrix进行实时监控的工具,通过Hystrix Dashboard我们可以在直观地看到各Hystrix Command的请求响应时间, 请求成功率等数据。但是只使用Hystrix Dashboard的话, 你只能看到单个应用内的服务信息, 这明显不够. 我们需要一个工具能让我们汇总系统内多个服务的数据并显示到Hystrix Dashboard上, 这个工具就是Turbine.
1、添加依赖
org.springframework.cloud
spring-cloud-starter-hystrix
org.springframework.cloud
spring-cloud-starter-hystrix-dashboard
org.springframework.boot
spring-boot-starter-actuator
2、启动类添加注解
@EnableHystrixDashboard
@EnableCircuitBreaker
3、测试
我们暂时只演示单个应用的所以在输入框中输入: http://localhost:9001/hystrix.stream ,输入之后点击 monitor,进入页面。
如果没有请求会先显示Loading …,访问http://localhost:9001/hystrix.stream 也会不断的显示ping。
请求服务http://localhost:9001/hello/neo,就可以看到监控的效果了,首先访问http://localhost:9001/hystrix.stream,显示如下:
在复杂的分布式系统中,相同服务的节点经常需要部署上百甚至上千个,很多时候,运维人员希望能够把相同服务的节点状态以一个整体集群的形式展现出来,这样可以更好的把握整个系统的状态。 为此,Netflix提供了一个开源项目(Turbine)来提供把多个hystrix.stream的内容聚合为一个数据源供Dashboard展示。
1、pom文件
org.springframework.cloud
spring-cloud-starter-turbine
org.springframework.cloud
spring-cloud-netflix-turbine
org.springframework.boot
spring-boot-starter-actuator
org.springframework.cloud
spring-cloud-starter-hystrix-dashboard
2、配置文件
spring.application.name=hystrix-dashboard-turbine
server.port=8001
turbine.appConfig=node01,node02
turbine.aggregator.clusterConfig= default
turbine.clusterNameExpression= new String("default")
eureka.client.serviceUrl.defaultZone=http://localhost:8000/eureka/
turbine.appConfig :配置Eureka中的serviceId列表,表明监控哪些服务
turbine.aggregator.clusterConfig :指定聚合哪些集群,多个使用”,”分割,默认为default。可使用http://…/turbine.stream?cluster={clusterConfig之一}访问
turbine.clusterNameExpression : 1. clusterNameExpression指定集群名称,默认表达式appName;此时:turbine.aggregator.clusterConfig需要配置想要监控的应用名称;2. 当clusterNameExpression: default时,turbine.aggregator.clusterConfig可以不写,因为默认就是default;3. 当clusterNameExpression: metadata[‘cluster’]时,假设想要监控的应用配置了eureka.instance.metadata-map.cluster: ABC,则需要配置,同时turbine.aggregator.clusterConfig: ABC
3、启动类
@EnableTurbine
@EnableHystrixDashboard