1.Eureka概述

(1)引子

网约车出现以前,人们出门叫车只能叫出租车。一些私家车想做出租却没有资格,被称为黑车。而很多人想要约车,但是无奈出租车太少,不方便。私家车很多却不敢拦,而且满大街的车,谁知道哪个才是愿意载人的。一个想要,一个愿意给,就是缺乏管理啊。
此时滴滴这样的网约车平台出现了,所有想载客的私家车全部到滴滴注册,记录你的车型(服务类型),身份信息(联系方式)。这样提供服务的私家车,在滴滴那里都能找到,一目了然。
此时要叫车的人,只需要打开APP,输入你的目的地,选择车型(服务类型),滴滴自动安排一个符合需求的车到你面前,为你服务,完美!

Eureka就好比是滴滴,负责管理、记录服务提供者的信息。服务调用者无需自己寻找服务,而是把自己的需求告诉Eureka,然后Eureka会把符合你需求的服务告诉服务调用者。
同时,服务提供方与Eureka之间通过`“心跳”`机制进行监控,当某个服务提供方出现问题,Eureka自然会把它从服务列表中剔除。这就实现了服务的自动注册、发现、状态监控。

小结:eureka是一个注册中心,用于服务的注册与发现。
(2)原理图

- Eureka:就是服务注册中心(可以是一个集群),对外暴露自己的地址
- 提供者:启动后向Eureka注册自己信息(地址,提供什么服务)
- 消费者:向Eureka订阅服务,Eureka会将对应服务的所有提供者地址列表发送给消费者,并且定期更新
- 心跳(续约):提供者定期通过http方式向Eureka刷新自己的状态

2.入门案例

我们创建一个项目,启动一个EurekaServer

(1)Spring脚手架(Spring Initializr)创建工程

自动生成的pom文件

<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.1.RELEASE</version> <relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>lucky.eureka</groupId>
<artifactId>lucky-eureka</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>lucky-eureka</name>
<description>Demo project for Spring Boot</description> <properties>
<java.version>1.8</java.version>
<spring-cloud.version>Greenwich.SR2</spring-cloud.version>
</properties> <dependencies>
<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>
</dependencyManagement> <build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build> </project>

(2)代码部分

<1>编写application.yml配置:

server:
port: 10086 # 端口
spring:
application:
name: eureka-server # 应用名称,会在Eureka中显示
eureka:
client:
service-url: # EurekaServer的地址,现在是自己的地址,如果是集群,需要加上其它Server的地址。
defaultZone: http://localhost:${server.port}/eureka

<2>修改引导类,在类上添加@EnableEurekaServer注解:

package lucky.eureka;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer; @SpringBootApplication
@EnableEurekaServer //启用eureka服务端
public class LuckyEurekaApplication { public static void main(String[] args) {
SpringApplication.run(LuckyEurekaApplication.class, args);
} }

(3)效果图

 3.注册到Eureka

修改lucky-service-provider工程
-在pom.xml中,添加springcloud的相关依赖。
- 在application.yml中,添加springcloud的相关依赖
-在引导类上添加注解,把服务注入到eureka注册中心。

(1)pom文件

参照lucky-eureka,先添加SpringCloud依赖:

<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion> <parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.7.RELEASE</version> <relativePath/> <!-- lookup parent from repository -->
</parent> <groupId>lucky.service</groupId>
<artifactId>lucky-service-provider</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>lucky-service-provider</name>
<description>Demo project for Spring Boot</description> <properties>
<java.version>1.8</java.version>
<spring-cloud.version>Greenwich.SR2</spring-cloud.version>
</properties> <dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.1.0</version>
</dependency> <dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency> <!-- 通用mapper -->
<dependency>
<groupId>tk.mybatis</groupId>
<artifactId>mapper-spring-boot-starter</artifactId>
<version>2.0.2</version>
</dependency> <!-- Eureka客户端 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</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>
</dependencyManagement>

<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build> </project>

(2)application.yml

server:
port: 8081
spring:
datasource:
url: jdbc:mysql://localhost:3306/springboot?serverTimezone=UTC&useSSL=false
username: root
password: plj824
application:
name: service-provider #注册到eureka后的微服务的名称
mybatis:
type-aliases-package: lucky.service.domain
eureka:
client:
service-url:
defaultZone: http://localhost:10086/eureka

注意:

这里我们添加了spring.application.name属性来指定应用名称,将来会作为应用的id使用。

jdbc的url版本8.0以上要加时区

(3)引导类

在引导类上开启Eureka客户端功能

通过添加@EnableDiscoveryClient来开启Eureka客户端功能

package lucky.service;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.test.context.junit4.SpringRunner; @RunWith(SpringRunner.class)
@SpringBootTest
@EnableDiscoveryClient //启用eureka客户端
public class LuckyServiceProviderApplicationTests { @Test
public void contextLoads() {
} }

效果图:

4.从Eureka获取服务,解决消费方url地址的硬编码问题

(1)pom文件修改内容与注册服务相同

(2)修改配置

server:
port: 8080
logging:
level:
root: info
spring:
application:
name: service-consumer #注册到eureka后的微服务的名称
eureka:
client:
service-url:
defaultZone: http://localhost:10086/eureka

(3)引导类

在引导类上开启Eureka客户端功能

通过添加@EnableDiscoveryClient来开启Eureka客户端功能

package lucky.service;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.context.annotation.Bean;
import org.springframework.web.client.RestTemplate; @SpringBootApplication
@EnableDiscoveryClient
public class LuckyServiceConsumerApplication { @Bean
public RestTemplate restTemplate() {
return new RestTemplate();
} public static void main(String[] args) {
SpringApplication.run(LuckyServiceConsumerApplication.class, args);
} }

(4)修改UserController代码,用DiscoveryClient类的方法,根据服务名称,获取服务实例

package lucky.service.controller;

import lucky.service.domain.Users;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.client.RestTemplate; import java.util.List; @Controller
@RequestMapping(path = "/consumer/user")
public class UserController {
@Autowired
private RestTemplate restTemplate; @Autowired
private DiscoveryClient discoveryClient; // eureka客户端,可以获取到eureka中服务的信息 @RequestMapping(path = "/queryUsersById")
@ResponseBody
public Users queryUserById(@RequestParam("id") Integer id){ // 根据服务名称,获取服务实例。有可能是集群,所以是service实例集合
List<ServiceInstance> instances = discoveryClient.getInstances("service-provider");
// 因为只有一个Service-provider。所以获取第一个实例
ServiceInstance instance = instances.get(0);
// 获取ip和端口信息,拼接成服务地址
String baseUrl = "http://" + instance.getHost() + ":" + instance.getPort() + "/users/queryUsersById?id=" + id;
Users user = this.restTemplate.getForObject(baseUrl, Users.class);
return user;
} }

(5)效果图

输入网址:http://localhost:8080/consumer/user/queryUsersById?id=2

 

5.高可用的Eureka Server

Eureka Server即服务的注册中心,在刚才的案例中,我们只有一个EurekaServer,事实上EurekaServer也可以是一个集群,形成高可用的Eureka中心。

(1)服务同步

多个Eureka Server之间也会互相注册为服务,当服务提供者注册到Eureka Server集群中的某个节点时,该节点会把服务的信息同步给集群中的每个节点,从而实现数据同步。因此,无论客户端访问到Eureka Server集群中的任意一个节点,都可以获取到完整的服务列表信息。

(2)动手搭建高可用的EurekaServer

我们假设要运行两个EurekaServer的集群,端口分别为:10086和10087。只需要把itcast-eureka启动两次即可。

<1>启动第一个eurekaServer,我们修改原来的EurekaServer配置:

server:
port: 10086 # 端口
spring:
application:
name: eureka-server # 注册到eureka中显示的应用名称
eureka:
client:
service-url: # 配置其他Eureka服务的地址,而不是自己,比如10087
defaultZone: http://localhost:10087/eureka

所谓的高可用注册中心,其实就是把EurekaServer自己也作为一个服务进行注册,这样多个EurekaServer之间就能互相发现对方,从而形成集群。因此我们做了以下修改:把service-url的值改成了另外一台EurekaServer的地址,而不是自己

启动报错,很正常。因为10087服务没有启动:

<2>启动第二个eurekaServer,再次修改itcast-eureka的配置:

注意:idea中一个应用不能启动两次,我们需要重新配置一个启动器:

然后启动即可。

<3>访问集群,测试:

最新文章

  1. 深入理解javascript原型和闭包(12)——简介【作用域】
  2. .NET Core第三方开源Web框架YOYOFx
  3. iOS开发基础知识碎片
  4. php 使用redis锁限制并发访问类
  5. svg学习(七)polygon
  6. 获取url据对路径写法
  7. jQuery ajax - get(),getJSON(),post()方法
  8. 【转】SVN服务器搭建--Subversio与TortoiseSVN的配置安装
  9. 爬虫技术(四)-- 简单爬虫抓取示例(附c#代码)
  10. jQuery幻灯插件:Nivo Slider
  11. 单词缩写(abbr.cpp)每日一题
  12. dev使用3
  13. spring之p命名空间注入
  14. python一行代码就能搞定的事情!
  15. LeetCode第一次刷题
  16. GNU Wget 1.19.1 static built on mingw32
  17. Golang 笔记 3 if、switch、for、select语句
  18. 强化学习9-Deep Q Learning
  19. STM32F103C8开发板原理图和管脚图
  20. 从invalidAuthenticationToken❌想到需要忽略:verify_authenticity_token。

热门文章

  1. python - django 将图片路径地址转换成 InMemoryUploadedFile 并存储数据库
  2. Trolley slow
  3. openjudge1.1
  4. 使用charles对jmeter进行抓包
  5. Python 元编程
  6. dedecms复制网上的带有图片的文章,图片不能自动下载到本地的解决方法
  7. window系统对应默认IE浏览器版本
  8. python skimage图像处理(三)
  9. Python + Selenium 自动发布文章(一):开源中国
  10. Android之WebRTC介绍(二)