一. Eureka的基本架构
Spring Cloud 封装了 Netflix 公司开发的 Eureka 模块来实现服务注册和发现(请对比Zookeeper)。
Netflix在设计Eureka时遵守的就是AP原则。CAP原则又称CAP定理,指的是在一个分布式系统中,Consistency(一致性)、 Availability(可用性)、Partition tolerance(分区容错性),三者不可兼得
Eureka 采用了 C-S 的设计架构。Eureka Server 作为服务注册功能的服务器,它是服务注册中心。
而系统中的其他微服务,使用 Eureka 的客户端连接到 Eureka Server并维持心跳连接。这样系统的维护人员就可以通过 Eureka Server 来监控系统中各个微服务是否正常运行。SpringCloud 的一些其他模块(比如Zuul)就可以通过 Eureka Server 来发现系统中的其他微服务,并执行相关的逻辑。
二. Eureka三大角色
Eureka Server提供服务注册与发现
Service Provider服务提供方将自身服务注册到Eureka,从而使服务消费方能够找到
Service Consumer服务方从Eureka获取服务注册列表,从而能够消费服务
三. 搭建微服务工程
1.新建整体父工程microservicecloud
- 新建时选择打包方式为pom
- 修改pom.xml文件
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<junit.version>4.12</junit.version>
<log4j.version>1.2.17</log4j.version>
<lombok.version>1.16.18</lombok.version>
</properties>
<dependencyManagement>
<dependencies>
<!-- SpringCloud版本 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Dalston.SR1</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>1.5.9.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.0.4</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.0.31</version>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>1.3.0</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-core</artifactId>
<version>1.2.3</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>${junit.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>${log4j.version}</version>
</dependency>
</dependencies>
</dependencyManagement>
2.新建公共子模块microservice-api(封装整体entity、接口、公共配置等)
- 查看pom.xml
<!-- 子类里面显示声明才能有明确的继承表现,无意外就是父类的默认版本否则自己定义 -->
<parent>
<groupId>com.nhkj.springcloud</groupId>
<artifactId>microservicecloud</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<!-- 当前Module我自己叫什么名字 -->
<artifactId>microservicecloud-api</artifactId>
- 新建实体类Dept
public class Dept implements Serializable {
private Long deptno; //主键
private String dname; //部门名称
private String db_source; // 来自那个数据库,因为微服务架构可以一个服务对应一个数据库,同一个信息被存储到不同数据库
public Long getDeptno() {
return deptno;
}
public void setDeptno(Long deptno) {
this.deptno = deptno;
}
public String getDname() {
return dname;
}
public void setDname(String dname) {
this.dname = dname;
}
public String getDb_source() {
return db_source;
}
public Dept() {
super();
}
public void setDb_source(String db_source) {
this.db_source = db_source;
}
}
3.新建微服务提供者microservicecloud-provider-dept-8001
- 修改pom.xml
<dependencies>
<dependency><!-- 引入自己定义的api通用包,可以使用Dept部门Entity -->
<groupId>com.nhkj.springcloud</groupId>
<artifactId>microservicecloud-api</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-core</artifactId>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jetty</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
</dependency>
<!-- 修改后立即生效,热部署 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>springloaded</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
</dependency>
</dependencies>
- 在resource目录下新家application.yml
server:
port: 8001
mybatis:
config-location: classpath:mybatis/mybatis.cfg.xml # mybatis配置文件所在路径
type-aliases-package: com.nhkj.springcloud.entities # 所有Entity别名类所在包
mapper-locations:
- classpath:mybatis/mapper/**/*.xml # mapper映射文件
spring:
application:
name: microservicecloud-dept #非常重要 对外暴露的微服务名称
datasource:
type: com.alibaba.druid.pool.DruidDataSource # 当前数据源操作类型
driver-class-name: org.gjt.mm.mysql.Driver # mysql驱动包
url: jdbc:mysql://localhost:3306/cloudDB01 # 数据库名称
username: root
password: a123456
dbcp2:
min-idle: 5 # 数据库连接池的最小维持连接数
initial-size: 5 # 初始化连接数
max-total: 5 # 最大连接数
max-wait-millis: 200 # 等待连接获取的最大超时时间
- 服务提供者8001目录结构
- 8001的启动类
@SpringBootApplication
public class DeptProvider8001_App {
public static void main(String[] args) {
SpringApplication.run(DeptProvider8001_App.class, args);
}
}
4.部门微服务消费者microservicecloud-consumer-dept-80
- 修改pom.xml
<dependencies>
<dependency><!-- 自己定义的api -->
<groupId>com.nhkj.springcloud</groupId>
<artifactId>microservicecloud-api</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- 修改后立即生效,热部署 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>springloaded</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
</dependency>
</dependencies>
- 新建application.yml文件
server:
port: 80
- com.nhkj.springcloud.cfgnbeans包下ConfigBean的编写(类似spring里面的applicationContext.xml写入的注入bean)
@SpringBootConfiguration
public class ConfigBean {
@Bean
public RestTemplate getRestTemplate() {
return new RestTemplate();
}
}
这里介绍一下RestTemplate是什么:RestTemplate提供了多种便捷访问远程Http服务的方法,是一种简单便捷的访问restful服务模板类,是Spring提供的用于访问Rest服务的客户端模板工具集。
@RestController
@RequestMapping("customer")
public class DeptController_Consumer {
//private static final String REST_URL_PREFIX = "http://localhost:8001";//通过端口号访问
private static final String REST_URL_PREFIX = "HTTP://MICROSERVICECLOUD-DEPT";//通过微服务名称访问
@Autowired
private RestTemplate restTemplate;
// @SuppressWarnings("unchecked")
@RequestMapping(value = "/dept/list")
public List<Dept> list(){
return restTemplate.getForObject(REST_URL_PREFIX + "/dept/list", List.class);
}
}
- 80微服务的启动类
@SpringBootApplication
public class DeptConsumer80_App {
public static void main(String[] args) {
SpringApplication.run(DeptConsumer80_App.class, args);
}
}
5.服务注册中心microservicecloud-eureka-7001
- 修改pom.xml文件
<dependencies>
<!--eureka-server服务端 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka-server</artifactId>
</dependency>
<!-- 修改后立即生效,热部署 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>springloaded</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
</dependency>
</dependencies>
- 新建application.yml
server:
port: 7001
eureka:
instance:
hostname: localhost #eureka服务端的实例名称
client:
register-with-eureka: false #false表示不向注册中心注册自己。
fetch-registry: false #false表示自己端就是注册中心,我的职责就是维护服务实例,并不需要去检索服务
service-url:
defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/ #设置与Eureka Server交互的地址查询服务和注册服务都需要依赖这个地址。
- EurekaServer7001启动类
@SpringBootApplication
@EnableEurekaServer//EurekaServer服务器端启动类,接受其它微服务注册进来
public class EurekaServer7001_App{
public static void main(String[] args) {
SpringApplication.run(EurekaServer7001_App.class, args);
}
}
6.将已有的部门微服务(8001)注册进eureka服务中心
- 修改dept-8001的pom.xml文件
<!-- 将微服务provider侧注册进eureka -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-config</artifactId>
</dependency>
- 修改dept-8001的application.yml文件
eureka:
client: #客户端注册进eureka服务列表内
service-url:
defaultZone: http://localhost:7001/eureka
- 修改dept-8001的启动类
@SpringBootApplication
@EnableEurekaClient //本服务启动后会自动注册进eureka服务中
public class DeptProvider8001_App {
public static void main(String[] args) {
SpringApplication.run(DeptProvider8001_App.class, args);
}
}
四. actuator与注册微服务信息完善
1.主机名称:服务名称修改
修改dept-8001的application.yml文件
eureka:
client: #客户端注册进eureka服务列表内
service-url:
defaultZone: http://localhost:7001/eureka
#以下是修改内容
instance:
instance-id: microservicecloud-dept8001
2.访问信息有ip显示
修改dept-8001的application.yml文件
instance:
instance-id: microservicecloud-dept8001
#以下是修改内容
prefer-ip-address: true
3.微服务info内容详细信息
当前问题:点击微服务超链接出现ErrorPage
- 修改dept-8001的pom.xml文件
<!-- actuator监控信息完善 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
- 修改总的父工程的pom.xml文件
<build>
<finalName>microservicecloud</finalName>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
</resource>
</resources>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<configuration>
<delimiters>
<delimit>$</delimit>
</delimiters>
</configuration>
</plugin>
</plugins>
</build>
- 修改dept-8001的application.yml文件
info:
app.name: wanbangee-microservicecloud
company.name: www.wanbangee.com
build.artifactId: $project.artifactId$
build.version: $project.version$
五. eureka自我保护
导致原因:某时刻某一个微服务不可用,eureka不会立刻清理,依旧会对该微服务的信息进行保存
六. 集群配置
1.以eureka-7001为模板创建eureka-7002和eureka-7003
注意点:
分别修改7001、7002、7003的yml配置文件,以7002为例
server:
port: 7002
eureka:
instance:
hostname: eureka7002.com #eureka服务端的实例名称
client:
register-with-eureka: false #false表示不向注册中心注册自己。
fetch-registry: false #false表示自己端就是注册中心,我的职责就是维护服务实例,并不需要去检索服务
service-url:
#以下是修改部分
defaultZone: http://eureka7001:7001/eureka/,http://eureka7003:7003/eureka/ #设置与Eureka Server交互的地址查询服务和注册服务都需要依赖这个地址。
2.将dept-8001微服务发布到上面3台eureka集群配置中
eureka:
client: #客户端注册进eureka服务列表内
service-url:
#以下是修改部分
defaultZone: http://eureka7001.com:7001/eureka/,http://eureka7002.com:7002/eureka/,http://eureka7003.com:7003/eureka/