SpringCloud 系列 --1.Eureka 集群

本贴最后更新于 1845 天前,其中的信息可能已经时移世异

image.png

由于一台电脑做测试,需要配置 host
127.0.0.1 slave1 slave2

1. Eureka 服务

application.yml

server: port: 8761 spring: application: name: first-cloud-server profiles: slave1 eureka: instance: hostname: slave1 client: serviceUrl: defaultZone: http://slave2:8762/eureka/ --- server: port: 8762 spring: application: name: first-cloud-server profiles: slave2 eureka: instance: hostname: slave2 client: serviceUrl: defaultZone: http://slave1:8761/eureka/

启动类,通过命令行指定 profile 文件

package org.crazyit.cloud; import java.util.Scanner; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.builder.SpringApplicationBuilder; import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer; @SpringBootApplication @EnableEurekaServer public class FirstServer { public static void main(String[] args) { // 读取控制台输入,决定使用哪个profiles Scanner scan = new Scanner(System.in); String profiles = scan.nextLine(); new SpringApplicationBuilder(FirstServer.class).profiles(profiles).run(args); } }

slave1 使用端口 8761,slave2 使用端口 8762
当使用 slave1 这个 profiles 来启动服务器时,将会向 http://slave2:8762/eureka/注册自己,
使用 slave2 启动服务时候,会向 http://slave1:8761/eureka/注册自己,
简单点说,就是这两个服务启动后(分别用 slave1,slave2 这两个 profile 来启动同一个程序),他们会相互注册。

启动两次该程序,访问分别如下:
image.png
image.png

2. 服务提供者

application.yml 将服务注册到两个 eureka 服务上

spring: application: name: first-cloud-provider eureka: instance: hostname: localhost client: serviceUrl: defaultZone: http://localhost:8761/eureka/,http://localhost:8762/eureka/

启动类 ,使用 @EnableEurekaClient 注解,并接收命令行输入启动指定端口

package org.crazyit.cloud; import java.util.Scanner; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.builder.SpringApplicationBuilder; import org.springframework.cloud.netflix.eureka.EnableEurekaClient; @SpringBootApplication @EnableEurekaClient public class FirstServiceProvider { public static void main(String[] args) { // 读取控制台输入的端口,避免端口冲突 Scanner scan = new Scanner(System.in); String port = scan.nextLine(); new SpringApplicationBuilder(FirstServiceProvider.class).properties( "server.port=" + port).run(args); } }

Controller 返回请求的地址:( 为了查看结果,将请求的 URL 设置到 Person 实例中)

package org.crazyit.cloud; import javax.servlet.http.HttpServletRequest; import org.springframework.http.MediaType; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RestController; @RestController public class FirstController { @RequestMapping(value = "/person/{personId}", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE) public Person findPerson(@PathVariable("personId") Integer personId, HttpServletRequest request) { Person person = new Person(personId, "Crazyit", 30); // 为了查看结果,将请求的URL设置到Person实例中 person.setMessage(request.getRequestURL().toString()); return person; } }

Person.java

package org.crazyit.cloud; public class Person { private Integer id; private String name; private Integer age; private String message; public Person() { super(); } public Person(Integer id, String name, Integer age) { super(); this.id = id; this.name = name; this.age = age; } public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } public String getMessage() { return message; } public void setMessage(String message) { this.message = message; } }

3. 服务调用者

将服务注册到两个 eureka 服务上 application.yml

server: port: 9000 spring: application: name: first-cloud-invoker eureka: instance: hostname: localhost client: serviceUrl: defaultZone: http://slave1:8761/eureka/,http://slave12:8761/eureka/

4.编写 REST 客户端进行测试

使用 httpclient
pom.xml 如下:

<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>org.crazyit.cloud</groupId> <artifactId>first-cloud-rest-client</artifactId> <version>0.0.1-SNAPSHOT</version> <dependencies> <dependency> <groupId>org.apache.httpcomponents</groupId> <artifactId>httpclient</artifactId> <version>4.5.2</version> </dependency> </dependencies> </project>

测试类如下:
调用 6 次服务调用者的接口,观察输出

package org.crazyit.cloud; import org.apache.http.HttpResponse; import org.apache.http.client.methods.HttpGet; import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.HttpClients; import org.apache.http.util.EntityUtils; public class TestHttpClient { public static void main(String[] args) throws Exception { // 创建默认的HttpClient CloseableHttpClient httpclient = HttpClients.createDefault(); // 调用6次服务并输出结果 for(int i = 0; i < 6; i++) { // 调用 GET 方法请求服务 HttpGet httpget = new HttpGet("http://localhost:9000/router"); // 获取响应 HttpResponse response = httpclient.execute(httpget); // 根据 响应解析出字符串 System.out.println(EntityUtils.toString(response.getEntity())); } } }

允许测试类 main 方法输出如下:

{"id":1,"name":"Crazyit","age":30,"message":"http://localhost:8861/person/1"}
{"id":1,"name":"Crazyit","age":30,"message":"http://localhost:8862/person/1"}
{"id":1,"name":"Crazyit","age":30,"message":"http://localhost:8861/person/1"}
{"id":1,"name":"Crazyit","age":30,"message":"http://localhost:8862/person/1"}
{"id":1,"name":"Crazyit","age":30,"message":"http://localhost:8861/person/1"}
{"id":1,"name":"Crazyit","age":30,"message":"http://localhost:8862/person/1"}

Process finished with exit code 0

说明负载均衡已生效。

同样在浏览器中访问多次结果会在两台机器上轮换。
image.png

image.png

补充:

如果把 8861 停掉,所有请求都会到 8862 上面。
image.png

此时的 eureka 中显示 provider 也会变成一个
image.png

服务都启动的时候如下:(红色的提示先不用管,启动一会之后就正常了)
image.png

相关帖子

欢迎来到这里!

我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。

注册 关于
请输入回帖内容 ...