专栏首页小小码农一个。SpringCloud 入门之Eureka 篇

SpringCloud 入门之Eureka 篇

前言

Spring Cloud 是一系列框架的有序集合。它利用 Spring Boot 的开发便利性巧妙地简化了分布式系统基础设施的开发,如服务发现注册、配置中心、消息总线、负载均衡、断路器、数据监控等,都可以用 Spring Boot 的开发风格做到一键启动和部署。

本篇介绍 Spring Cloud 入门系列中的 Eureka,实现快速入门。

简单介绍

Eureka 是 Netflix 的子模块,它是一个基于 REST 的服务,用于定位服务,以实现云端中间层服务发现和故障转移。

服务注册和发现对于微服务架构而言,是非常重要的。有了服务发现和注册,只需要使用服务的标识符就可以访问到服务,而不需要修改服务调用的配置文件。该功能类似于 Dubbo 的注册中心,比如 Zookeeper。

Eureka 采用了 CS 的设计架构。Eureka Server 作为服务注册功能的服务端,它是服务注册中心。而系统中其他微服务则使用 Eureka 的客户端连接到 Eureka Server 并维持心跳连接。

其运行原理如下图:

由图可知,Eureka 的运行原理和 Dubbo 大同小异, Eureka 包含两个组件: Eureka Server 和 Eureka Client。

Eureka Server 提供服务的注册服务。各个服务节点启动后会在 Eureka Server 中注册服务,Eureka Server 中的服务注册表会存储所有可用的服务节点信息。

Eureka Client 是一个 Java 客户端,用于简化 Eureka Server 的交互,客户端同时也具备一个内置的、使用轮询负载算法的负载均衡器。在应用启动后,向 Eureka Server 发送心跳(默认周期 30 秒)。如果 Eureka Server 在多个心跳周期内没有接收到某个节点的心跳,Eureka Server 会从服务注册表中将该服务节点信息移除。

搭建注册中心

创建 Spring Boot 项目,名为 eureka-server,进行如下操作:

添加依赖

<dependencyManagement>
  <dependencies>
  	<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-starter-parent</artifactId>
		<version>1.5.9.RELEASE</version>
		<type>pom</type>
		<scope>import</scope>
	</dependency>
  </dependencies>
</dependencyManagement>
  
<dependencies>  
    <!-- eureka 服务端 -->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-eureka-server</artifactId>
    </dependency>
</dependencies>

Spring Boot 与 SpringCloud 有版本兼容关系,如果引用版本不对应,项目启动会报错。

application.yml 配置参数

server:
    port: 9000
    
eureka:
    instance:
        hostname: localhost   # eureka 实例名称
    client:
        register-with-eureka: false # 不向注册中心注册自己
        fetch-registry: false       # 是否检索服务
        service-url:
            defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/  # 注册中心访问地址

开启注册中心功能

在启动类上添加 @EnableEurekaServer 注解。

至此,准备工作完成,启动项目完成后,浏览器访问 http://localhost:9000 ,查看 Eureka 服务监控界面,如下图:

通过该网址可以查看注册中心注册服务的相关信息。当前还没有服务注册,因此没有服务信息。

补充:http://localhost:9000 是 Eureka 监管界面访问地址,而 http://localhost:9000/eureka/ Eureka 注册服务的地址。

实战演练

了解 Eureka 的环境搭建后,我们需要进行实战直观的感受 Eureka 的真正作用,这样才能清楚掌握和学习 Eureka 。

我们再创建两个 Spring Boot 项目,一个名为 user-api ,用于提供接口服务,另一个名为 user-web,用于调用 user-api 接口获取数据与浏览器交互。 服务实例 端口 描述 eureka 9000 注册中心(Eureka 服务端) user-api 8081 服务提供者(Eureka 客户端) user-web 80 服务消费者,与浏览器端交互(Eureka 客户端)

user-api 项目部分代码(服务提供)

<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-web</artifactId>
</dependency>

<!-- eureka 客户端 -->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-eureka</artifactId>
</dependency>

配置参数

server:
    port: 8081
 
spring:
    application:
        name: user-api

eureka:
    instance:
        instance-id: user-api-8081
        prefer-ip-address: true # 访问路径可以显示 IP
    client:
        service-url:
            defaultZone: http://localhost:9000/eureka/  # 注册中心访问地址

服务接口:

public interface UserService {
    public User getById(Integer id);
}

@Service
public class UserServiceImpl implements UserService {
	
	private static Map<Integer,User> map;
	
	static {
		map = new HashMap<>();
		for (int i=1; i<6; i++) {
			map.put(i, new User(i,"test" +i , "pwd" + i));
		}
	}

	@Override
	public User getById(Integer id) {
		return map.get(id);
	}

}
@RestController
@RequestMapping("/provider/user")
public class UserController {
	
	@Autowired
	private UserService userService;

	@RequestMapping("/get/{id}")
	public User get(@PathVariable("id") Integer id) {
		return this.userService.getById(id);
	}
}

注意:该 controller 是给 user-web 使用的(内部服务),不是给浏览器端调用的。

开启服务注册功能:

在启动类上添加 @EnableEurekaClient 注解。

启动项目完成后,浏览器访问 http://localhost:9000 查看 Eureka 服务监控界面 ,如下图:

从图可知,user 相关服务信息已经注册到 Eureka 服务中了。

补充:在上图中,我们还看到一串红色的字体,那是因为 Eureka 启动了自我保护的机制。当 EurekaServer 在短时间内丢失过多客户端时(可能发生了网络故障),EurekaServer 将进入自我保护模式。进入该模式后,EurekaServer 会保护服务注册表中的信息不被删除。当网络故障恢复后,EurekaServer 会自动退出自我保护模式。

user-web 项目部分代码(服务消费)

<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-web</artifactId>
</dependency>

<!-- eureka 客户端 -->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-eureka</artifactId>
</dependency>

配置参数

server:
  port: 80
 
spring:
  application:
    name: user-web
      
eureka:
  client:
    register-with-eureka: false # 不向注册中心注册自己
    fetch-registry: true        # 是否检索服务
    service-url:
      defaultZone: http://localhost:9000/eureka/  # 注册中心访问地址

客户端:

@Configuration
public class RestConfiguration {

	@Bean
	@LoadBalanced
	public RestTemplate getRestTemplate() {
		return new RestTemplate();
	}
}
@RestController
@RequestMapping("/user")
public class UserController {
	
	@Autowired
	private RestTemplate restTemplate;
	
//	@RequestMapping("get/{id}")
//	public User get(@PathVariable("id") Integer id) throws Exception {
//		// 没有使用 Eureka 时,uri 为消息提供者的地址,需要指定 ip 和 端口
//		return restTemplate.getForObject(new URI("http://localhost:8081/provider/user/get/" + id), User.class);
//	}

    @Autowired
	private DiscoveryClient client;
	
	@RequestMapping("get/{id}")
	public User get(@PathVariable("id") Integer id) throws Exception {
		
		List<ServiceInstance> list = this.client.getInstances("USER-API");
		String uri = "";
	    for (ServiceInstance instance : list) {
	        if (instance.getUri() != null && !"".equals(instance.getUri())) {
	        	uri = instance.getUri().toString();
	        	break;
	        }
	    }
		return restTemplate.getForObject(uri + "/provider/user/get/" + id, User.class);
	}
	
}

开启服务发现功能:

在启动类上添加 @EnableDiscoveryClient 注解。

启动项目后,使用浏览器访问 user-web 项目接口,运行结果如下:

源码下载

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • Ribbon负载均衡

    策略规则 Ribbon 提供 IRule 接口,该接口定义了如何访问服务的策略,以下是该接口的实现类:

    崔笑颜
  • redis学习(八)

    朋友的定位,附近的人,打车距离计算? Redis 的 Geo 在Redis3.2 版本就推出了! 这个功能可以推算地理位置的信息,两地之间的距离,方圆 几里...

    崔笑颜
  • redis学习(十六)

    Redis 是内存数据库,如果不将内存中的数据库状态保存到磁盘,那么一旦服务器进程退出,服务器中 的数据库状态也会消失。所以 Redis 提供了持久化功能!

    崔笑颜
  • 做网站留后门的网站制作公司不能选

    无论是做公司网站还是其他类型的网站,如果你发现做网站的公司做的网站留有后门,在网站上线后,网站制作公司仍可以自由通过后门权限对网站后台进行操作的,最好还是换一家...

    天津做网站-美耐思
  • nginx反向代理https网站 并实现网站的注册和登录功能

    image.png 最近给我们官网做了新加坡、香港、美国、加拿大地区的反代,由于现阶段发展有限,只好选择这种最节约的方法了,但并非负载均衡,负载均衡等后期商城确...

    速企云
  • mybatis源码解读(一)——初始化环境

    IT可乐
  • Redis基础知识(一)

    Redis 是一个开源的使用 ANSI C 语言编写、遵守 BSD 协议、支持网络、可基于内存亦可持久化的日志型、Key-Value 数据库,并提供多种语言的 ...

    没有故事的陈师傅
  • 「微服务架构」面向CTO的微服务设计模式:API网关、前端的后端等

    微服务体系结构是软件开发中最热门的趋势之一。作为CTO,你需要知道何时使用它们。但你也需要对这个主题有更深入的了解才能真正掌握你的项目。通过进一步了解微服务中的...

    首席架构师智库
  • 学会这15点,让你分分钟拿下Redis数据库

    REmote DIctionary Server(Redis) 是一个由Salvatore Sanfilippo写的key-value存储系统。Red...

    民工哥
  • 如何使用 EXPLAIN 精准查看执行计划?

    在上一篇中 如何使用慢查询快速定位执行慢的 SQL?定位了查询慢的 SQL 之后,我们就可以使用 EXPLAIN 工具做针对性的分析,比如我们想要了解 prod...

    极客小智

扫码关注云+社区

领取腾讯云代金券