1 为什么要使用注册中心
- 微服务数量众多,要进行远程调用就需要知道服务端的ip地址和端口,注册中心帮助我们管理这些服务的ip和端口。
- 微服务会实时上报自己的状态,注册中心统一管理这些微服务的状态,将存在问题的服务踢出服务列表,客户端获取到可用的服务进行调用。
2 Eureka注册中心
2.1 介绍
Spring Cloud Eureka 是对Netflix公司的Eureka的二次封装,它实现了服务治理的功能,Spring Cloud Eureka提供服务端与客户端,服务端即是Eureka服务注册中心,客户端完成微服务向Eureka服务的注册与发现。服务端和客户端均采用Java语言编写。下图显示了
Eureka Server
与Eureka Client
的关系:Eureka Server
是服务端,负责管理各各微服务结点的信息和状态- 在微服务上部署
Eureka Client
程序,远程访问Eureka Server
将自己注册在Eureka Server
。 - 微服务需要调用另一个微服务时从
Eureka Server
中获取服务调用地址,进行远程调用。
2.2 Eureka Server搭建
2.2.1 单机环境搭建
2.2.1.1 创建工程
- 创建
xc-govern-center
工程
2.2.1.2 添加依赖
- 父工程pom文件(有了就不用重复添加)
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Finchley.SR1</version>
<type>pom</type>
<scope>import</scope>
</dependency>
Eureka Server
工程
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
</dependencies>
2.2.1.3 启动类
GovernCenterApplication
package com.xuecheng.govern.center;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;
@EnableEurekaServer //表示此工程是一个EurekaServer
@SpringBootApplication
public class GovernCenterApplication {
public static void main(String[] args) {
SpringApplication.run(GovernCenterApplication.class);
}
}
- <font color="red">需要在启动类上用
@EnableEurekaServer
标识此服务为Eureka服务</font>
2.2.1.4 application.yml
server:
port: 50101 #服务端口
spring:
application:
name: xc-govern-center #指定服务名
eureka:
client:
register-with-eureka: false #注册服务,是否将自己注册到Eureka服务中
fetch-registry: false #服务发现,是否从Eureka中获取注册信息
service-url: #Eureka客户端与Eureka服务端的交互地址,高科用状态配置对方的地址,单机状态配置自己(如果不配置默认本机)
defaultZone: :http://localhost:50101/eureka/ #本机
server:
enable-self-preservation: false #是否开启自我保护模式,微服务因网络问题断开但是是活的,仍在注册中心中注册
eviction-interval-timer-in-ms: 60000 #服务注册表清理间隔(单位毫秒,默认是60*1000)
register-with-eureka
:被其它服务调用时需向Eureka注册fetch-registry
:需要从Eureka中查找要调用的目标服务时需要设置为true
service-url.defaultZone
: 配置上报Eureka服务地址高可用状态配置对方的地址,单机状态配置自己enable-self-preservation
:自保护设置。eviction-interval-timer-in-ms
:清理失效结点的间隔,在这个时间段内如果没有收到该结点的上报则将结点从服务列表中剔除。
2.2.1.5 logback-spring.xml
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<!--定义日志文件的存储地址,使用绝对路径-->
<property name="LOG_HOME" value="d:/logs"/>
<!-- Console 输出设置 -->
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符-->
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
<charset>utf8</charset>
</encoder>
</appender>
<!-- 按照每天生成日志文件 -->
<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!--日志文件输出的文件名-->
<fileNamePattern>${LOG_HOME}/xc.%d{yyyy-MM-dd}.log</fileNamePattern>
</rollingPolicy>
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
</encoder>
</appender>
<!-- 异步输出 -->
<appender name="ASYNC" class="ch.qos.logback.classic.AsyncAppender">
<!-- 不丢失日志.默认的,如果队列的80%已满,则会丢弃TRACT、DEBUG、INFO级别的日志 -->
<discardingThreshold>0</discardingThreshold>
<!-- 更改默认的队列的深度,该值会影响性能.默认值为256 -->
<queueSize>512</queueSize>
<!-- 添加附加的appender,最多只能添加一个 -->
<appender-ref ref="FILE"/>
</appender>
<logger name="org.apache.ibatis.cache.decorators.LoggingCache" level="DEBUG" additivity="false">
<appender-ref ref="CONSOLE"/>
</logger>
<logger name="org.springframework.boot" level="DEBUG"/>
<root level="info">
<!--<appender-ref ref="ASYNC"/>-->
<appender-ref ref="FILE"/>
<appender-ref ref="CONSOLE"/>
</root>
</configuration>
注意
<font color="red">**THE SELF PRESERVATION MODE IS TURNED OFF.THIS MAY NOT PROTECT INSTANCE EXPIRY IN CASE OF
NETWORK/OTHER PROBLEMS.(自我保护模式被关闭。在网络或其他问题的情况下可能不会保护实例失效。)**</font>Eureka Server
有一种自我保护模式,当微服务不再向Eureka Server
上报状态,Eureka Server
会从服务列表将此服务删除,如果出现网络异常情况(微服务正常),此时Eureka server
进入自保护模式,不再将微服务从服务列表删除。- <font color="red">在开发阶段建议关闭自保护模式。</font>
2.2.2 高可用环境搭建
Eureka Server
高可用环境需要部署两个Eureka server
,它们互相向对方注册。如果在本机启动两个Eureka需要注意两个Eureka Server
的端口要设置不一样,这里我们部署一个Eureka Server
工程,将端口可配置,制作两个Eureka Server
启动脚本,启动不同的端口
- 在实际使用时
Eureka Server
至少部署两台服务器,实现高可用。 - 两台
Eureka Server
互相注册。 - 微服务需要连接两台
Eureka Server
注册,当其中一台Eureka死掉也不会影响服务的注册与发现。 - 微服务会定时向
Eureka server
发送心跳,报告自己的状态。 - 微服务从注册中心获取服务地址以
RESTful
方式发起远程调用。
2.2.2.1 端口配置
server:
port: ${PORT:50101} #服务端口 没有找到PORT这个环境变量的话,默认端口为50101
2.2.2.2 Eureka服务端的交互地址可配置
eureka:
client:
register-with-eureka: true #注册服务,是否将自己注册到Eureka服务中
fetch-registry: true #服务发现,是否从Eureka中获取注册信息
service-url: #Eureka客户端与Eureka服务端的交互地址,高科用状态配置对方的地址,单机状态配置自己(如果不配置默认本机)
defaultZone: ${EUREKA_SERVER:http://eureka02:50102/eureka/} #环境变量EUREKA_SERVER
2.2.2.3 配置hostname
- 由于本机测试,需要修改
hosts
文件。Eureka 组成高可用,两个Eureka互相向对方注册,这里需要通过域名或主机名访问,这里我们设置两个Eureka服务的主机名分别为 eureka01、eureka02。
127.0.0.1 eureka01
127.0.0.1 eureka02
instance:
hostname: ${EUREKA_DOMAIN:eureka01}
2.2.2.4 完整application.yml
server:
port: ${PORT:50101} #服务端口 没有找到PORT这个环境变量的话,默认端口为50101
spring:
application:
name: xc-govern-center #指定服务名
eureka:
client:
register-with-eureka: true #注册服务,是否将自己注册到Eureka服务中
fetch-registry: true #服务发现,是否从Eureka中获取注册信息
service-url: #Eureka客户端与Eureka服务端的交互地址,高科用状态配置对方的地址,单机状态配置自己(如果不配置默认本机)
defaultZone: ${EUREKA_SERVER:http://eureka02:50102/eureka/} #环境变量EUREKA_SERVER
server:
enable-self-preservation: false #是否开启自我保护模式
eviction-interval-timer-in-ms: 60000 #服务注册表清理间隔(单位毫秒,默认是60*1000)
instance:
hostname: ${EUREKA_DOMAIN:eureka01}
2.2.2.5 IDEA启动脚本
- 启动实例1——eureka01
-DPORT=50101 -DEUREKA_SERVER=http://eureka02:50102/eureka/ -DEUREKA_DOMAIN=eureka01
- 启动实例2——eureka02
-DPORT=50102 -DEUREKA_SERVER=http://eureka01:50101/eureka/ -DEUREKA_DOMAIN=eureka02
- 启动结果,访问
localhost:50101
或localhost:50102
如下图:
2.3 微服务注册
2.3.1 在服务项目pom中添加依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
2.3.2 application.yml
- 新增
eureka
部分
server:
port: ${PORT:31001}
spring:
application:
name: xc-service-manage-cms
data:
mongodb:
uri: mongodb://localhost:27017
database: xc_cms
rabbitmq:
host: 127.0.0.1
port: 5672
username: guest
password: guest
virtualHost: /
freemarker:
cache: false #关闭模板缓存,方便测试
settings:
template_update_delay: 0
eureka:
client:
register-with-eureka: true #服务注册开关
fetch-registry: true #服务发现开关
service-url: #Eureka客户端与Eureka服务端进行交互的地址,多个中间用逗号分隔
defaultZone: ${EUREKA_SERVER:http://localhost:50101/eureka/,http://localhost:50102/eureka/}
instance:
prefer-ip-address: true #将自己的ip注册到Eureka服务中
ip-address: ${IP_ADDRESS:127.0.0.1}
instance-id: ${spring.application.name}:${server.port} #指定实例Id
2.3.3 启动类上添加注解@EnableDiscoveryClient
@EnableDiscoveryClient
package com.xuecheng.manage_cms;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.domain.EntityScan;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.data.mongodb.gridfs.GridFsTemplate;
import org.springframework.http.client.OkHttp3ClientHttpRequestFactory;
import org.springframework.web.client.RestTemplate;
@EnableDiscoveryClient //一个EurekaClient从EurekaServer发现服务
@SpringBootApplication
@EntityScan("com.xuecheng.framework.domain.cms")//扫描实体类
@ComponentScan(basePackages = "com.xuecheng.api")//扫描接口
@ComponentScan(basePackages = "com.xuecheng.framework")//扫描commom包下的类,不然自定义异常用不了
@ComponentScan(basePackages = "com.xuecheng.manage_cms")//扫描本项目下的所有类
public class ManageCmsApplication {
public static void main(String[] args) {
SpringApplication.run(ManageCmsApplication.class);
}
@Bean
public RestTemplate restTemplate() {
return new RestTemplate(new OkHttp3ClientHttpRequestFactory());
}
}
One comment
哈哈哈,写的太好了https://www.cscnn.com/