SpringCloud 系列 --1.Eureka 集群

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

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

相关帖子

欢迎来到这里!

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

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