Spring Boot做为目前最火爆的web框架。那么spring boot与Eureka又有什么关联呢?前端
Eureka是Netflix开源的一个RESTful服务,主要用于服务的注册发现。
Eureka由两个组件组成:Eureka服务器和Eureka客户端。Eureka服务器用做服务注册服务器。
Eureka客户端是一个java客户端,用来简化与服务器的交互、做为轮询负载均衡器,并提供服务的故障切换支持。
Netflix在其生产环境中使用的是另外的客户端,它提供基于流量、资源利用率以及出错状态的加权负载均衡。
SpringCloud Eureka是SpringCloud Netflix服务套件中的一部分,它基于Netflix Eureka作了二次封装,主要负责完成微服务架构中的服务治理功能。java
咱们在建立新的项目时,若是选择了相关SpringCloud的依赖,则会自动在pom.xml配置文件内添加SpringCloud最新稳定版本依赖配置。
spring-cloud-dependencies这个依赖是SpringCloud内所须要依赖的版本维护,在maven项目内若是被<dependencyManagement>内修饰的<dependency>,子项目或者本项目在使用时能够不用设置版本号,默认使用<dependencyManagement>下<dependency>内设置的版本信息。
正因如此,这也是为何咱们添加了spring-cloud-dependencies依赖后,在使用相关SpringCloud插件时能够不用添加version标签设置导入指定版本的依赖。web
新建maven项目,其中pom.xml内容以下:spring
<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.vincent</groupId> <artifactId>spring-cloud-eureka-server</artifactId> <version>1.0-SNAPSHOT</version> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <maven.compiler.source>1.8</maven.compiler.source> <maven.compiler.target>1.8</maven.compiler.target> </properties> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-dependencies</artifactId> <version>2.1.4.RELEASE</version> <scope>import</scope> <type>pom</type> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>Greenwich.RELEASE</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> <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> </dependencies> </project>
能够看到,这里与普通的springboot惟一区别是添加了eureka-server依赖包。如何使用Eureka?apache
仅仅须要在启动类上开启一个注解@EnableEurekaServer就能够,App.java以下:浏览器
package com.vincent; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer; /** * Created by iie4b on 2019-6-18 21:27 */ @SpringBootApplication @EnableEurekaServer public class App { public static void main(String[] args) { SpringApplication.run(App.class, args); } }
配置application.properties,内容以下:springboot
server.port=8080 eureka.instance.hostname=127.0.0.1 # 是否向服务中心注册本身 eureka.client.register-with-eureka=false # 是否检索服务 eureka.client.fetch-registry=false # 服务注册中心的配置内容,指定服务注册中心的位置 eureka.client.service-url.defaultZone=http://${eureka.instance.hostname}:${server.port}/eureka/
其中“defaultZone”是一个魔术字符串后备值,为任何不表示首选项的客户端提供服务URL(即它是有用的默认值)。服务器
Eureka是一个高可用的组件,每个实例注册以后须要向注册中心发送心跳包,在默认状况下erureka server也是一个eureka client ,必需要指定一个 server。eureka.client.register-with-eureka=false表示是否向注册中心注册本身,默认为true,true将会在注册中心看到server本身的服务。架构
启动App.java,在浏览器上输入http://127.0.0.1:8080/app
能够看到可视化界面,可是咱们发现这里并无Application服务,“No instances available”,若是设置eureka.client.register-with-eureka=true将会在这里显示出本身的服务,目前尚未其余服务向服务中心注册,因此没有其余服务。
当客户端注册Eureka时,它提供关于自身的元数据,例如主机和端口,健康指示符URL,主页等。Eureka从属于服务的每一个实例接收心跳消息。若是心跳失败超过可配置的时间表,则一般将该实例从注册表中删除。
新建maven项目,其中pom.xml内容以下:
<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.vincent</groupId> <artifactId>spring-cloud-eureka-provider-A-1</artifactId> <version>1.0-SNAPSHOT</version> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <maven.compiler.source>1.8</maven.compiler.source> <maven.compiler.target>1.8</maven.compiler.target> </properties> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-dependencies</artifactId> <version>2.1.4.RELEASE</version> <scope>import</scope> <type>pom</type> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>Greenwich.RELEASE</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> <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> </dependencies> </project>
client的依赖与server的依赖几乎同样。
在Spring-boot的启动类上经过注解@EnableEurekaClient 代表本身是一个eurekaclient.
App.java内容以下:
package com.vincent; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.netflix.eureka.EnableEurekaClient; /** * Created by vincent on 2019-6-18 21:56 */ @SpringBootApplication @EnableEurekaClient public class App { public static void main(String[] args) { SpringApplication.run(App.class, args); } }
同时provider-A项目提供一个服务,新建controller/UserController.java
package com.vincent.controller; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RestController; import java.util.HashMap; import java.util.Map; /** * Created by vincent on 2019-6-18 21:58 */ @RestController public class UserController { @GetMapping("/user/{name}") public Map<String,Object> getUser(@PathVariable("name") String userName) { Map<String,Object> data = new HashMap<>(); data.put("id",userName); data.put("from","provider-A-1"); return data; } }
而后配置application.properties,内容以下:
# 注册中心的注册地址 eureka.client.service-url.defaultZone=http://127.0.0.1:8080/eureka/ # 服务名称--调用的时候根据名称来调用该服务的方法 spring.application.name=service-provider-A server.port=8081
启动App.java
从界面里咱们能够看到,这个客户端已经向注册中心注册服务了,刷新http://localhost:8080/
能够看到SERVICE-PROVIDER-A-1已经成功加入进去了。
有标红的,由于注册的服务都是高可用的,这里只检测到一个服务,产生的预警,不影响使用,等下咱们启动多个实例就不会了。
测试客户端方法是否可用:
说明客户端正常。
这个服务提供者与上一个服务提供者几乎同样。pom.xml以下:
<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.vincent</groupId> <artifactId>spring-cloud-eureka-provider-A-2</artifactId> <version>1.0-SNAPSHOT</version> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <maven.compiler.source>1.8</maven.compiler.source> <maven.compiler.target>1.8</maven.compiler.target> </properties> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-dependencies</artifactId> <version>2.1.4.RELEASE</version> <scope>import</scope> <type>pom</type> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>Greenwich.RELEASE</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> <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> </dependencies> </project>
为了与provider-A-1区别,provider-A-2中的UserController.java以下:
@RestController public class UserController { @GetMapping("/user/{name}") public Map<String,Object> getUser(@PathVariable("name") String userName) { Map<String,Object> data = new HashMap<>(); data.put("id",userName); data.put("from","provider-A-2"); return data; } }
provider-A-2中的application.properties以下:
# 注册中心的注册地址 eureka.client.service-url.defaultZone=http://127.0.0.1:8080/eureka/ # 服务名称--调用的时候根据名称来调用该服务的方法 spring.application.name=service-provider-A server.port=8082
注意这里的application.name都是service-provider-A
启动App.java
查看Eureka Server后台:
发现红色的警告没有了,由于咱们有了两个一样的服务,提供了高可用服务,还能够负载均衡。
这两个服务能够分别访问如下:
端口8081表示Provider-A-1的服务
端口8082表示Provider-A-2的服务
咱们目前已经提供好了服务provider-A-1和provider-A-2,而且他们有负载均衡的能力。接下来创建消费者,使用服务。
创建消费者,他的pom.xml以下:
<groupId>com.vincent</groupId> <artifactId>spring-cloud-eureka-consumer-A-1</artifactId> <version>1.0-SNAPSHOT</version> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <maven.compiler.source>1.8</maven.compiler.source> <maven.compiler.target>1.8</maven.compiler.target> </properties> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-dependencies</artifactId> <version>2.1.4.RELEASE</version> <scope>import</scope> <type>pom</type> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>Greenwich.RELEASE</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> <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> </dependencies>
创建ConsumerController.java
package com.vincent.controller; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.web.client.RestTemplateBuilder; import org.springframework.cloud.client.loadbalancer.LoadBalanced; import org.springframework.context.annotation.Bean; import org.springframework.web.bind.annotation.*; import org.springframework.web.client.RestTemplate; import java.util.HashMap; import java.util.Map; /** * Created by vincent on 2019-6-19 19:09 */ @RestController public class ConsumerController { // 启动的时候要注意,因为咱们在controller中注入了RestTemplate,因此启动的时候须要实例化该类的一个实例 @Autowired private RestTemplateBuilder builder; @Autowired private RestTemplate restTemplate; // 使用RestTemplateBuilder来实例化RestTemplate对象,spring默认已经注入了RestTemplateBuilder实例 @Bean @LoadBalanced public RestTemplate restTemplate() { return builder.build(); } /** * Rest服务端使用RestTemplate发起http请求,而后获得数据返回给前端 * @param username * @return */ @GetMapping(value = "/gotoUser/{username}") @ResponseBody public Map<String, Object> getUser(@PathVariable("username") String username) { Map<String, Object> data = new HashMap<>(); /** * 地址是http://service-provider * 而不是http://127.0.0.1:8082/ * 由于他向注册中心注册了服务,服务名称service-provider-A,咱们访问service-provider-A便可 */ data = restTemplate.getForObject("http://service-provider-A/user/" + username, Map.class); return data; } }
启动类App.java
@SpringBootApplication @EnableEurekaClient public class App { public static void main(String[] args) { SpringApplication.run(App.class, args); } }
consumer-A的application.properties内容以下:
# 注册中心的注册地址 eureka.client.service-url.defaultZone=http://127.0.0.1:8080/eureka/ # 服务名称--调用的时候根据名称来调用该服务的方法 spring.application.name=service-consumer-A server.port=8083
能够看到有两个服务提供方,一个消费者。由于消费者服务没有负载均衡,因此有警告,能够忽略。
访问消费者,浏览器输入http://localhost:8083/gotoUser/vincent
能够实现负载均衡,交替访问provider-A-1和provider-A-2。
每一个微服务都是一个Eureka-Client,咱们把每一个app(SpringBootApplication)都向注册中心注册一个服务。 有时候,某个服务的工做量比较大的时候,咱们能够多注册几个同名称的微服务,从而让他们交替工做,减轻单个服务的压力。