Eureka介绍
Eureka是Netflix开源的服务发现组件,本身是一个基于REST的服务。它包含Server和Client两部分。Spring Cloud将它集成在子项目Spring Cloud Netflix中,从而实现微服务的注册与发现。
Eureka包含两个组件:Eureka Server和EurekaClient,它们的作用如下:
●Eureka Server提供服务发现的能力,各个微服务启动时,会向Eureka Server注册自己的信息(例如IP、端口、微服务名称等),Eureka Server会存储这些信息。
●EurekaClient是一个Java客户端,用于简化与Eureka Server的交互。
●微服务启动后,会周期性(默认30s)地向Eureka Server发送心跳以续约自己的“租期”。
●如果Eureka Server在一定时间内没有接收到某个微服务实例的心跳,Eureka Server将注销该实例(默认90s)。
●默认情况下,Eureka Server同时也是EurekaClient。多个Eureka Server实例互相之间通过复制的方式来实现服务注册表中数据的同步。
●EurekaClient会缓存服务注册表中的信息。这种方式有一定的优势——首先,微服务无须每次请求都查询Eureka Server,从而降低了Eureka Server的压力;其次,即使Eureka Server所有节点都宕掉,服务消费者依然可以使用缓存中的信息找到服务提供者并完成调用。 综上,Eureka通过心跳检查、客户端缓存等机制,提高了系统的灵活性、可伸缩性和可用性。
工具准备
IDEA、mysql、新建springboot项目、其他相关jar包
在maven官网都可以搜到。
步骤
编写eureka server
1.新建两个springboot工程文件(maven)
一个是eureka server
pom.xml
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
yml:
server:
port: 8761
eureka:
client:
register-with-eureka: false
fetch-registry: false
serviceUrl.defaultZone: http://localhost:8761/eureka/
●eureka.client.registerWithEureka:表示是否将自己注册到EurekaServer,默认为true。由于当前应用就是Eureka Server,故而设为false。
●eureka.client.fetchRegistry:表示是否从Eureka Server获取注册信息,默认为true。因为这是一个单点的Eureka Server,不需要同步其他的Eureka Server节点的数据,故而设为false。
●eureka.client.serviceUrl.defaultZone:设置与EurekaServer交互的地址,查询服务和注册服务都需要依赖这个地址。默认是http://localhost:8761/eureka;多个地址间可使用,分隔。
运行启动类:
@SpringBootApplication
@EnableEurekaServer
public class EurekaServiceApplication {
public static void main(String[] args) {
SpringApplication.run(EurekaServiceApplication.class, args);
}
}
注意
●在Spring Cloud Edgware之前,要想将微服务注册到Eureka Server或其他服务发现组件上,必须在启动类上添加@EnableEurekaClient或@EnableDiscoveryClient。
●在SpringCloud Edgware以及更高版本中,只需添加相关依赖,即可自动注册。这是由于在实际项目中,我们可能希望实现“不同环境不同配置”的效果,例如:在开发环境中,不注册到EurekaServer上,而是服务提供者、服务消费者直连,便于调测;在生产环境中,我们又希望能够享受服务发现的优势——服务消费者无须知道服务提供者的绝对地址。为适应该需求,Spring Cloud Commons进行了改进,相关Issue:https://github.com/springcloud/spring-cloud-commons/issues/218.
启动成功:
编写微服务应用:
依赖:
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<!-- https://mvnrepository.com/artifact/com.h2database/h2 -->
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<version>1.4.200</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.6</version>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.1.2</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>2.0.6</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
yml注册到eureka的配置:
spring:
application:
name: clouddemo
server:
port: 8000
eureka:
client:
service-url:
defaultZone: http://localhost:8761/eureka/
instance:
prefer-ip-address: true
# 表示将自己的IP注册到eureka server,若不配置该属性或设置为false则表示注册微服务所在操作系统的hostname到eureka server
数据库配置:
spring.datasource.url=jdbc:mysql://localhost:3308/waimai?useUnicode=true&characterEncoding=UTF-8&useSSL=false&allowPublicKeyRetrieval=true&serverTimezone=GMT%2B8
spring.datasource.username=waimai
spring.datasource.password=123456
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.jpa.database-platform=org.hibernate.dialect.MySQL5InnoDBDialect
spring.jpa.show-sql=true
mybatis.type-aliases-package=com.example.springcloud.clouddemo.Entity
其中mybatis.type-aliases-package=com.example.springcloud.clouddemo.Entity
用于mybatis映射,由于用的是注解的方式所以只写这一句就好。
新建的数据表:
编写实体类、dao、controller层:
entity
@Data
@Entity
public class User {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long Id;
@Column
private String username;
@Column
private String name;
@Column
private Integer age;
@Column
private BigDecimal balance;
}
dao:
这里用的是注解的方式
@Mapper
public interface UserDao {
@Select("select Id,username,name,age,balance from userr")
List<User>SelectUser();
@Select("select Id,username,name,age,balance from userr where Id = #{Id}")
User SelectoneUser(int Id);
}
controller:
@RestController
public class UserController {
@Autowired
private UserDao userDao;
@GetMapping("/{Id}")
public User findById(@PathVariable int Id) {
System.out.println("fds");
User findOne = userDao.SelectoneUser(Id);
return findOne;
}
}
启动微服务后浏览器输入
可以看见返回了正确的一条数据,可见微服务启动成功。
然后刷新刚刚的eureka页面:
可以看到已经成功注册。
查询指定微服务在Eureka上的实例列表
修改上面微服务应用的controller:添加以下语句
import org.springframework.cloud.client.discovery.DiscoveryClient;
@RestController
public class UserController {
@Autowired
private UserDao userDao;
@GetMapping("/{Id}")
public User findById(@PathVariable int Id) {
System.out.println("fds");
User findOne = userDao.SelectoneUser(Id);
return findOne;
}
@Autowired
private DiscoveryClient discoveryClient;
@GetMapping("/user")
public List<ServiceInstance> showInfo(){
return this.discoveryClient.getInstances("clouddemo");
}
}
discoveryClient.getInstances可以用于查询指定微服务在eureka上的实例列表
打开浏览器:
Eureka的自我保护模式
进入自我保护模式最直观的体现,是EurekaServer首页输出的警告,如图
Eureka Server自我保护模式界面 默认情况下,如果EurekaServer在一定时间内没有接收到某个微服务实例的心跳,Eureka Server将注销该实例(默认为90s)。但是当网络分区故障发生时,微服务与EurekaServer之间无法正常通信,以上行为可能变得非常危险了——因为微服务本身其实是健康的,此时本不应该注销这个微服务。 Eureka通过“自我保护模式”来解决这个问题——当Eureka Server节点在短时间内丢失过多客户端时(可能发生了网络分区故障),那么这个节点就会进入自我保护模式。一旦进入该模式,Eureka Server就会保护服务注册表中的信息,不再删除服务注册表中的数据(也就是不会注销任何微服务)。当网络故障恢复后,该Eureka Server节点会自动退出自我保护模式。
在Spring Cloud中,可以使用eureka.server.enable-self-preservation=false禁用自我保护模式。
●Eureka与ZooKeeper做服务发现的对比:http://dockone.io/article/78.
在Status一栏有个UP,表示应用程序状态正常。应用状态还有其他取值,例如DOWN、OUT_OF_SERVICE、UNKNOWN等。只有标记为“UP”的微服务会被请求。 前文讲过,EurekaServer与EurekaClient之间使用心跳机制来确定EurekaClient的状态,默认情况下,服务器端与客户端的心跳保持正常,应用程序就会始终保持“UP”状态。