Eureka简介
Eureka就好比是一个控制中心,负责管理,记录服务提供者的信息。服务调用者无需自己寻找服务,而是把自己的需求告诉Eureka,然后Eureka会把符合你需求的服务告诉你。同时,服务提供方与Eureka之间通过“心跳”机制进行监控,当某个服务提供方出现问题,Eureka自然会把它从服务列表中剔除,这样就实现了服务的自动注册,发现,状态监控等。
在微服务架构中,服务注册与发现是核心组件之一,手动指定每个服务是很低效的,Spring Cloud提供了多种服务注册与发现的实现方式,例如:Eureka、Consul、Zookeeper;Spring Cloud 支持最好的就是Eureka,其次是Consul,再次是Xookeeper
什么是服务注册
服务注册:将服务所在主机,端口,版本号,通信协议等信息登记到注册中心上。
什么是服务发现
服务发现:服务消费者向注册中心请求已经登记的服务列表,然后得到某个服务的主机,端口,版本号,通信协议等信息,从而实现对具体业务的调用。
Eureka是什么
Eureka是一个服务治理组件,它主要包括服务注册和服务发现,用来搭建服务注册中心。
Eureka是一个基于REST的服务,用来定位服务,进行中间层服务器的负载均衡和故障转移。
Eureka是Netflix公司开发的,Spring Cloud封装了Netflix公司开发的,Eureka模块来实现服务注册和发现,也就是说Spring Cloud对Netflix Eureka做了二次封装。
Eureka架构设计
Eureka采用了C-S(客户端和服务端)的设计架构,也就是Eureka有两个组件组成:Eureka服务端和Eureka客户端。Eureka Server作为服务注册时服务端,就是注册服务中心,而系统中的其他微服务,使用了Eureka的客户端连接到Eureka Server 服务端,并维持心跳连接,Eureka客户端就是就是java客户端,用来简化与服务器的交互,负载均衡,服务的故障切换等
有了Eureka注册中心,系统的维护人员就可以通过Eureka Server 来监控系统中各个微服务是够正常运行。
Eureka与Zookeeper的比较
著名的CAP理论指出,一个分布式系统不可能同时满足C(一致性)、A(可用性)和P(分区容错性),由于分区容错性在是分布式系统中必须要保证的,因为我们只能在A和C之间进行权衡,在此Zookeeper保证的是CP,而Eureka则是AP
Zookeeper保证CP
在zookeeper中,当master节点因为网络故障与其他节点失去联系时,剩余的节点会重新进行leader选举,由于选举leader需要一定时间,且选举期间整个zookeeper集群都是不可用的,会导致选举期间注册服务瘫痪。
Eureka保证AP
Eureka优先保证可用性,Eureka各个节点是平等的,某几个节点挂掉不会影响正常节点的工作,剩余的节点依然可以提供注册和查询服务,而Eureka的客户端在向某个Eureka注册时发现注册失败,则会自动切换到其他节点,只能有一台Eureka存在,就能保证注册服务可用(保证可用性),只不过查到的信息可能不是最新的(不能保证一致性)。
搭建Eureka服务注册中心
- 创建springboot工程
- 添加相关依赖
- 编写配置文件
- 编写启动类
- 启动并测试Eureka服务注册中心
创建springboot工程
添加相关依赖
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.0.RELEASE</version>
</parent>
<!-- SpringCloud的依赖 -->
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Finchley.SR2</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
</dependencies>
编写配置文件
#配置服务端口
server:
port: 10086
#配置应用名称,会在Eureka中显示
spring:
application:
name: eureka-server
#EurekaServer的地址,现在是自己的地址,如果是集群,需要加上其他Server的地址
eureka:
client:
service-url:
defaultZone: http://127.0.0.1:${server.port}/eureka
# server:
# #失效剔除
# #扫描失效服务的间隔时间(缺省为60*1000)
# eviction-interval-timer-in-ms: 90
# #关闭自我保护模式(缺省为打开)
# enable-self-preservation: false
编写启动类
@SpringBootApplication
//声明当前springboot应用是一个eureka服务中心线
@EnableEurekaServer
public class SpringCloudEurekaServer {
public static void main(String[] args) {
SpringApplication.run(SpringCloudEurekaServer.class,args);
}
}
启动并测试Eureka服务注册中心
向Eureka服务注册中注册服务
模拟向数据库查询数据
- 创建springboot项目
- 添加依赖
- 编写配置文件
- 编写controller、service、mapper的代码
- 编写启动类
- 测试
创建springboot项目
添加依赖
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.0.RELEASE</version>
</parent>
<!-- SpringCloud的依赖 -->
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Finchley.SR2</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<!--Eureka客户端-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</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-jdbc</artifactId>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>1.3.2</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.47</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
</dependency>
</dependencies>
编写配置文件
server:
port: 8082
spring:
datasource:
url: jdbc:mysql://localhost:3306/ssm_crud
driver-class-name: com.mysql.jdbc.Driver
username: root
password: 1234
#应用名称,注册到eureka后的服务名称
application:
name: service-provider
mybatis:
type-aliases-package: com.lifly.pojo
mapper-locations: classpath:/mapper/*.xml
# 配置Mybatis日志输出信息
logging:
level:
com.lifly.mapper: debug
eureka:
client:
service-url:
#EruekaServer地址
defaultZone: http://127.0.0.1:10086/eureka
# instance:
# #服务失效时间,默认为90秒
# lease-expiration-duration-in-seconds: 90
# #服务血月(renew)的间隔值,默认为30秒
# lease-renewal-interval-in-seconds: 30
编写pojo、controller、service、mapper的代码
pojo
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Books {
/**
* book的id
*/
private Integer BookId;
/**
* book的书名
*/
private String bookName;
/**
* book的书名
*/
private Integer bookCounts;
/**
* book的书名
*/
private String detail;
}
mapper
@Repository
@Mapper
public interface BooksMapper{
public List<Books> findAllBooks();
public Books findBookById(int id);
}
<?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.lifly.mapper.BooksMapper">
<select id="findAllBooks" resultType="Books">
select * from books
</select>
<select id="findBookById" parameterType="int" resultType="Books">
select * from books where bookId = #{id}
</select>
</mapper>
service
public interface BooksService {
/**
* 查询所有图书
* @return
*/
public List<Books> findAllBooks();
/**
* 根据图书id查询图书信息
* @param id
* @return
*/
public Books findBookById(int id);
}
@Service
public class BooksServiceImpl implements BooksService {
@Autowired
private BooksMapper booksMapper;
@Override
public List<Books> findAllBooks() {
return booksMapper.findAllBooks();
}
@Override
public Books findBookById(int id) {
return booksMapper.findBookById(id);
}
}
controller
@RestController
@RequestMapping("/books")
public class BooksController {
@Autowired
private BooksService booksService;
@GetMapping("/all")
public List<Books> findAllBooks(){
return booksService.findAllBooks();
}
@GetMapping("/findBookById/{id}")
public Books findBookById(@PathVariable("id") int id){
return booksService.findBookById(id);
}
}
启动类
@SpringBootApplication
//开启Eureka客户端功能
@EnableDiscoveryClient
public class SpringBootEurekaClient {
public static void main(String[] args) {
SpringApplication.run(SpringBootEurekaClient.class,args);
}
}
测试
从上图中可以发现服务注册到注册中心了
测试代码
从图中可以看出基本的测试也能跑通
简单的Eureka服务注册中并向服务中心注册服务就实现了。