1.前言
经过上一篇博客的理论知识储备后,接下来我们正式开始Spring Cloud的学习。在微服务架构中,比较重要的组件就是分布式协调中心,即注册中心,目前常用的注册中心有Zookeeper、Eureka、Nacos,这里我们就重点来学习一下Eureka的使用。
开发环境
- JDK1.8
- Maven3
- IntelliJ IDEA
使用技术
- Spring Boot
- Spring Cloud
- Eureka
2.eureka-server的实现
既然被称为微服务项目,那么在项目中自然会出现多个module(模块),现在我们就来尝试编写一下。
首先,我们需要实现eureka-server
,即服务注册中心的逻辑。
- 创建一个普通的maven项目,不要勾选任何maven的可选模板,同时把src目录删除,因为我们在这里不需要它。
- 之后,创建服务注册中心。在当前项目中新建模块
eureka-server
,如图所示:
注意,如果这里你的网络不好,点击Next后可能会弹错,这是因为链接超时了,只需要再多重试几次即可。 - 编写模块的相应信息,让Group与父项目的包名一致,再设置Artifact为
eureka-server
,如图所示:(为了简略篇幅,以后在新建模块时Group都默认为你的父项目名,而Artifact为该段博客的标题,就不再贴出截图了)
- 点击Next后,选择对应依赖,这里只选择Eureka Server即可,如图所示:
- 创建该模块完成后,修改该模块的启动类,添加相应注解
@EnableEurekaServer
,表示这个类是Eureka的服务器端,代码如下:
package com.springclouddemo.eurekaserver;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;
@SpringBootApplication
@EnableEurekaServer
public class EurekaServerApplication {
public static void main(String[] args) {
SpringApplication.run(EurekaServerApplication.class, args);
}
}
- 修改resources目录下的
application.properties
,这里为了格式整洁用了yml
的格式,可以根据自己的需要进行选择,代码如下:
server:
port: 18761
eureka:
instance:
hostname: localhost
client:
register-with-eureka: false
fetch-registry: false
service-url:
defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/
这里简单地介绍一下配置文件的编写格式
使用eureka节点配置hostname
(可以认为是IP或者域名),然后最主要是设置service-url
,这里需要说下,对应的configuration类里面,service-url
是一个Map类型的,因为注册中心可以搭建集群,所以它的地址不是唯一的,当然,我们使用单机模式即可。
添加defaultZone
是因为它需要一个默认的注册中心地址。
我们先来说下fetch-registry
和register-with-eureka
,register-with-eureka
这个配置意思就是注册中心不把自己注册为服务提供者,因为本身注册中心是提供服务注册功能,并没有对外提供什么服务。
fetch-registry
当注册中心不把自己注册为服务后,也不需要从注册中心(自己)来同步服务消息了,所以也要设置为false。
- 以上的配置完成后,启动项目,使用浏览器访问
http://localhost:18761/
,若能够看到如下界面,说明服务启动成功
3.eureka-client的实现
我们在上面实现了eureka-server
,接下来我们需要实现eureka-client
,即服务提供者的逻辑。
- 同样创建一个新的模块,前面的步骤都相同,记得修改相应的Group和Artifact,即将Artifact改为
eureka-client
- 在选择相应的依赖时,我们这次选择Web和Eureka Discovery Client,如图所示:
- 创建好了该模块之后,修改启动类,添加注解
@EnableDiscoveryClient
表示这是一个客户端,然后实现一个显示当前端口的简单接口方法,代码如下:
package com.springclouddemo.eurekaclient;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@SpringBootApplication
@EnableDiscoveryClient
@RestController
public class EurekaClientApplication {
public static void main(String[] args) {
SpringApplication.run(EurekaClientApplication.class, args);
}
@Value("${server.port}")
String port;
@RequestMapping("/hi")
public String hi(){
return "IP:" + port;
}
}
- 修改application.yml(这里默认为properties,以下的描述全都为yml),注意区别端口,代码如下:
server:
port: 18762
eureka:
instance:
hostname: localhost
client:
service-url:
defaultZone: http://${eureka.instance.hostname}:18761/eureka/
spring:
application:
name: service-hi
-
先启动
eureka-server
,再启动eureka-client
,访问注册中心,可以看到我们注册的服务已经上线了,如图所示:
SERVICE-HI
即是我们在配置文件中定义的服务名,Eureka是用服务名作为唯一的标识,后边可以看到我们服务的地址信息
除此之外,我们还发现注册中心出现了一部分红色字体。
这个原因是Eureka注册中心在设置的阀值时间内,没有检测到活动的服务,则自己会进入保护机制(内部是15分钟心跳续约低于85%)。在生产环境下,因为网络延迟等原因,心跳失败实例的比例很有可能超标,但是此时就把服务剔除列表并不妥当,因为服务可能没有宕机。Eureka在这段时间内不会剔除任何服务实例,直到网络恢复正常。生产环境下这很有效,保证了大多数服务依然可用,不过也有可能获取到失败的服务实例,因此服务调用者必须做好服务的失败容错,可以通过在yml中配置来关停自我保护。
接下来,看看我们注册的服务在注册中心中是什么形式体现的。
主要关注Status状态,UP表示服务正常,DOWN表示服务在那时异常,但是如果在阀值时间内,还没有检测到心跳,则会剔除这个服务。
我们在SERVICE-HI
服务中,提供一个REST接口,通过网页来访问。 -
访问
http://localhost:18762/hi
,可以访问到刚才实现的方法,如图所示: