前言
微服务的服务与注册发现的功能非常重要,SpringCloud中的Eureka很方便的实现了这一功能
Eureka的主要功能:主要用来实现各个微服务实例的自动化注册与发现
必备知识
服务注册:在服务治理框架中,通常都会构建一个注册中心,每个服务单元向注册中心登记自己提供的服务,将主机与端口号、版本号、通信协议等一些附加信息告知注册中心,注册中心按照服务名分类组织服务清单,服务注册中心还需要以心跳的方式去监控清单中的服务是否可用,若不可用需要从服务清单中剔除,达到排除故障服务的效果。
服务发现:由于在服务治理框架下运行,服务间的调用不再通过指定具体的实例地址来实现,而是通过向服务名发起请求调用实现。
Eureka包含两个组件:Eureka Server和Eureka Client
Eureka Server提供服务注册服务
各个节点启动后,会在EurekaServer中进行注册,这样EurekaServer中的服务注册表中将会存储所有可用服务节点的信息,服务节点的信息可以在界面中直观的看到
EurekaClient是一个Java客户端,用于简化Eureka Server的交互,客户端同时也具备一个内置的、使用轮询(round-robin)负载算法的负载均衡器。在应用启动后,将会向Eureka Server发送心跳(默认周期为30秒)。如果Eureka Server在多个心跳周期内没有接收到某个节点的心跳,EurekaServer将会从服务注册表中把这个服务节点移除(默认90秒)
使用
1.建立一个微服务工程(客户机),并将已有的部门微服务注册进Eureka服务中心
pom.xml 里面有eureka的依赖,还有其他工程的依赖
<?xml version="1.0" encoding="UTF-8"?>
<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">
<parent>
<artifactId>demo1</artifactId>
<groupId>com.yan</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>demo-procider-dept-8001</artifactId>
<dependencies>
<!--actuator监控的依赖-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<!-- 将微服务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>
<!-- 引入自己定义的api通用包,可以使用Dept部门pojo -->
<dependency>
<groupId>com.yan</groupId>
<artifactId>demo-api</artifactId>
<version>${project.version}</version>
</dependency>
<!--单元测试支持-->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
</dependency>
<!--mysql数据库支持-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<!--阿里巴巴druid数据源管理-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
</dependency>
<!--日志logback-->
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-core</artifactId>
</dependency>
<!--mybatis整合-->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
</dependency>
<!--使用boot的jetty服务器-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jetty</artifactId>
</dependency>
<!--boot的web组件-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--boot的测试组件-->
<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>
</project>
application.xml 里面关于eureka的
1.做单个服务器/集群配置
defaultZone: http://eureka7001.com:7001/eureka/,http://eureka7002.com:7002/eureka/,http://eureka7003.com:7003/eureka/
2.微服务的别名使用及ip地址的显示
instance: # 起个别名,好于其他服务分开
instance-id: democloud-dept8001
prefer-ip-address: true #访问路径可以显示IP地址
3.错我信息页面处理 这里面会以JSON的形式打印想要的信息
info:
app.name: atguigu-microservicecloud
company.name: www.atguigu.com
build.artifactId:
p
r
o
j
e
c
t
.
a
r
t
i
f
a
c
t
I
d
{project.artifactId}
project.artifactId
build.version:
p
r
o
j
e
c
t
.
v
e
r
s
i
o
n
{project.version}
project.version
server:
port: 8001
mybatis:
config-location: classpath:mybatis/mybatis.xml # mybatis配置文件所在路径
type-aliases-package: com.yan.cloudapi.pojo # 所有Entity别名类所在包
mapper-locations:
- classpath:mybatis/mapper/**/*.xml # mapper映射文件
spring:
application:
name: democloud-dept # 对外暴露的微服务名称,是唯一标识
datasource:
type: com.alibaba.druid.pool.DruidDataSource # 当前数据源操作类型
driver-class-name: com.mysql.cj.jdbc.Driver # mysql驱动包
url: jdbc:mysql://localhost:3306/cloudDB01?useUnicode=true&characterEncoding=UTF-8&serverTimezone=GMT # 数据库名称
username: root
password: 123456
dbcp2:
min-idle: 5 # 数据库连接池的最小维持连接数
initial-size: 5 # 初始化连接数
max-total: 5 # 最大连接数
max-wait-millis: 200 # 等待连接获取的最大超时时间
eureka:
client: #客户端注册进eureka服务列表内 设置注册地址使用eureka
service-url:
#defaultZone: http://localhost:7001/eureka 单个服务器
defaultZone: http://eureka7001.com:7001/eureka/,http://eureka7002.com:7002/eureka/,http://eureka7003.com:7003/eureka/
#这里做了集群配置
instance: # 起个别名,好于其他服务分开
instance-id: democloud-dept8001
prefer-ip-address: true #访问路径可以显示IP地址
# 下面是错误页面信息处理
info:
app.name: atguigu-microservicecloud
company.name: www.atguigu.com
build.artifactId: ${project.artifactId}$
build.version: ${project.version}$
mybatis.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<settings>
<setting name="cacheEnabled" value="true"/><!-- 二级缓存开启 -->
</settings>
</configuration>
DeptDao
package com.yan.cloud.dao;
import com.yan.cloudapi.pojo.Dept;
import org.apache.ibatis.annotations.Mapper;
import java.util.List;
/**
* @Author: 闫明辉
* @Description:
* @Date: Create in 10:47 2020/3/1
*/
@Mapper
public interface DeptDao {
public boolean addDept(Dept dept);
public Dept findById(Long id);
public List<Dept> findAll();
}
DeptMapper.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.yan.cloud.dao.DeptDao">
<select id="findById" resultType="Dept" parameterType="Long">
select deptno,dname,db_source from dept where deptno=#{deptno};
</select>
<select id="findAll" resultType="Dept">
select deptno,dname,db_source from dept;
</select>
<insert id="addDept" parameterType="Dept">
INSERT INTO dept(dname,db_source) VALUES(#{dname},DATABASE());
</insert>
</mapper>
DeptService
package com.yan.cloud.service;
import com.yan.cloudapi.pojo.Dept;
import java.util.List;
/**
* @Author: 闫明辉
* @Description:
* @Date: Create in 10:52 2020/3/1
*/
public interface DeptService {
public boolean add(Dept dept);
public Dept get(Long id);
public List<Dept> list();
}
DeptServiceImpl
package com.yan.cloud.service.impl;
import com.yan.cloud.dao.DeptDao;
import com.yan.cloud.service.DeptService;
import com.yan.cloudapi.pojo.Dept;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
/**
* @Author: 闫明辉
* @Description:
* @Date: Create in 11:03 2020/3/1
*/
@Service
public class DeptServiceImpl implements DeptService {
@Autowired
private DeptDao dao;
@Override
public boolean add(Dept dept) {
return dao.addDept(dept);
}
@Override
public Dept get(Long id) {
return dao.findById(id);
}
@Override
public List<Dept> list() {
return dao.findAll();
}
}
controller eureka的服务发现
获取所有微服务的信息
package com.yan.cloud.controller;
import com.yan.cloud.service.DeptService;
import com.yan.cloudapi.pojo.Dept;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.web.bind.annotation.*;
import java.util.List;
/**
* @Author: 闫明辉
* @Description:
* @Date: Create in 11:08 2020/3/1
*/
@RestController
public class DeptController {
@Autowired
private DeptService service;
@Autowired
private DiscoveryClient client;
@RequestMapping(value = "/dept/add", method = RequestMethod.POST)
public boolean add(@RequestBody Dept dept) {
return service.add(dept);
}
@RequestMapping(value = "/dept/get/{id}", method = RequestMethod.GET)
public Dept get(@PathVariable("id") Long id) {
return service.get(id);
}
@RequestMapping(value = "/dept/list", method = RequestMethod.GET)
public List<Dept> list() {
return service.list();
}
//寻找所有微服务,并打印id,主机名字,端口,访问地址
@RequestMapping(value = "/dept/discovery", method = RequestMethod.GET)
public Object discovery()
{
List<String> list = client.getServices();
System.out.println("**********" + list);
List<ServiceInstance> srvList = client.getInstances("democloud-dept");
for (ServiceInstance element : srvList) {
System.out.println(element.getServiceId() + "\t" + element.getHost() + "\t" + element.getPort() + "\t"
+ element.getUri());
}
return this.client;
}
}
主启动类 关于eureka
@EnableEurekaClient //本服务启动后会自动注册进eureka服务中
@EnableDiscoveryClient//服务发现
package com.yan.cloud;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
/**
* @Author: 闫明辉
* @Description:
* @Date: Create in 11:18 2020/3/1
*/
@SpringBootApplication
@EnableEurekaClient //本服务启动后会自动注册进eureka服务中
@EnableDiscoveryClient//服务发现
public class DeptProvider8001_App {
public static void main(String[] args) {
SpringApplication.run(DeptProvider8001_App.class, args);
}
}
2.建立服务机,并且是集群
新建3个工程eureka7001、eureka7002、eureka7003
pom.xml 三个工程依赖相同
<?xml version="1.0" encoding="UTF-8"?>
<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">
<parent>
<artifactId>demo1</artifactId>
<groupId>com.yan</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>demo-eureka-7001</artifactId>
<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>
</project>
7001的application.xml
server:
port: 7001
eureka:
instance:
hostname: eureka7001.com #eureka服务端的实例名称
client:
register-with-eureka: false #false表示不向注册中心注册自己。
fetch-registry: false #false表示自己端就是注册中心,我的职责就是维护服务实例,并不需要去检索服务
service-url:
#单机 defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/ #设置与Eureka Server交互的地址查询服务和注册服务都需要依赖这个地址(单机)。
defaultZone: http://eureka7002.com:7002/eureka/,http://eureka7003.com:7003/eureka/
7002的application.xml
server:
port: 7002
eureka:
instance:
hostname: eureka7002.com #eureka服务端的实例名称
client:
register-with-eureka: false #false表示不向注册中心注册自己。
fetch-registry: false #false表示自己端就是注册中心,我的职责就是维护服务实例,并不需要去检索服务
service-url:
#defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/ #设置与Eureka Server交互的地址查询服务和注册服务都需要依赖这个地址。
defaultZone: http://eureka7001.com:7001/eureka/,http://eureka7003.com:7003/eureka/
7003的application.xml
server:
port: 7003
eureka:
instance:
hostname: eureka7003.com #eureka服务端的实例名称
client:
register-with-eureka: false #false表示不向注册中心注册自己。
fetch-registry: false #false表示自己端就是注册中心,我的职责就是维护服务实例,并不需要去检索服务
service-url:
#defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/ #设置与Eureka Server交互的地址查询服务和注册服务都需要依赖这个地址。
defaultZone: http://eureka7001.com:7001/eureka/,http://eureka7002.com:7002/eureka/
主启动类 由于3个工程非常相似,贴出一个就可以了
@EnableEurekaServer//Eureka Server服务器端启动类,接受其它微服务注册进来
package com.demo.cloud;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;
/**
* @Author: 闫明辉
* @Description:
* @Date: Create in 11:40 2020/3/2
*/
@SpringBootApplication
@EnableEurekaServer//Eureka Server服务器端启动类,接受其它微服务注册进来
public class EurekaServer7001_App {
public static void main(String[] args) {
SpringApplication.run(EurekaServer7001_App.class, args);
}
}
3.父类工程(之前搭建好的的)修改,做错我信息页面的提示
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>
4.修改电脑系统映射配置,做集群配置
win10系统在C:\Windows\System32\drivers\etc下的hosts文件加入以下配置
127.0.0.1 eureka7001.com
127.0.0.1 eureka7002.com
127.0.0.1 eureka7003.com
至此,搭建完成
测试
1.服务注册中心 箭头是是所有注册的微服务的列表,这里只做了一个微服务,故显示一个
2.主机名称服务名称
这显示的就是yml配置文件中instance的内容
3.访问信息出现IP显示 不爆IP
4.微服务Info内容
5.服务发现 不爆IP
6.集群测试
访问http://eureka7001.com:7001/
正常显示7002 7003 及注册进来的微服务可以点击出现提示页面服务名称修改,IP显示
访问http://eureka7002.com:7002/
正常显示7002 7003 及注册进来的微服务可以点击出现提示页面服务名称修改,IP显示
访问http://eureka7003.com:7003/
正常显示7002 7003 及注册进来的微服务可以点击出现提示页面服务名称修改,IP显示
参考资料:尚硅谷周阳Spring Cloud讲解