上篇文章《SpringCloud之Eureka:服务发布与调用例子》实现了一个简单例子,这次对其进行改造,运行两个服务器实例、两个服务提供者实例,服务调用者请求服务,使其可以进行集群部署。

集群结构如下图所示。

由于开发环境只有一台电脑,要构建集群,需要修改hosts文件,在里面添加主机名映射。

127.0.0.1 slave1 slave2

一、服务器端

1、创建项目

开发工具:IntelliJ IDEA 2019.2.2
IDEA中创建一个新的SpringBoot项目,名称为“first-cloud-server”,SpringBoot版本选择2.1.9,在选择Dependencies(依赖)的界面勾选Spring Cloud Discovery ->

Eureka Server,创建完成后的pom.xml配置文件自动添加SpringCloud最新稳定版本依赖,当前为Greenwich.SR3。
pom.xml完整内容可参考上篇文章《SpringCloud之Eureka:服务发布与调用例子》。

2、修改配置application.yml

由于需要对同一个应用程序启动两次,因此需要使用profiles配置。
下面配置了两个profiles,名称分别为slave1和slave2,当使用slave1启动服务器后,会向http://slave2:8762/eureka/注册自己,当使用slave2启动服务器后,会向

http://slave1:8761/eureka/注册自己,即两个服务器启动后,互相注册。

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/

3、修改启动类代码FirstEkServerApplication.java

除了增加注解@EnableEurekaServer,还让类在启动时读取控制台输入,决定使用哪个profiles来启动服务器。

package com.example.firstcloudserver;

import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer; import java.util.Scanner; @SpringBootApplication
@EnableEurekaServer
public class FirstCloudServerApplication { public static void main(String[] args) {
//SpringApplication.run(FirstCloudServerApplication.class, args);
Scanner scan = new Scanner(System.in);
String profiles = scan.nextLine();
new SpringApplicationBuilder(FirstCloudServerApplication.class)
.profiles(profiles).run(args);
} }

二、编写服务提供者

1、创建项目

IDEA中创建一个新的SpringBoot项目,除了名称为“first-cloud-provider”,其它步骤和上面创建服务器端一样。

2、修改配置application.yml

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

3、添加类 User.java

package com.example.firstcloudprovider;

public class User {
private Integer id;
private String name;
private String message; public User(Integer id, String name){
this.id = id;
this.name = name;
} 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 String getMessage() {
return message;
} public void setMessage(String message) {
this.message = message;
}
}

4、添加控制器 UserController.java

package com.example.firstcloudprovider;

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; import javax.servlet.http.HttpServletRequest; @RestController
public class UserController {
@RequestMapping(value = "/user/{userId}", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
public User findUser(@PathVariable("userId") Integer userId, HttpServletRequest request){
User user = new User(userId, "gdjlc");
user.setMessage(request.getRequestURL().toString());
return user;
}
}

5、修改启动类代码FirstCloudProviderApplication.java

除了增加注解@EnableEurekaClient,还让类在启动时读取控制台输入,决定使用哪个端口启动服务器。

package com.example.firstcloudprovider;

//import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient; import java.util.Scanner; @SpringBootApplication
@EnableEurekaClient
public class FirstCloudProviderApplication { public static void main(String[] args) {
//SpringApplication.run(FirstCloudProviderApplication.class, args);
Scanner scan = new Scanner(System.in);
String port = scan.nextLine();
new SpringApplicationBuilder(FirstCloudProviderApplication.class).properties("server.port=" + port).run(args);
} }

三、编写服务调用者

1、创建项目
IDEA中创建一个新的SpringBoot项目,除了名称为“first-cloud-invoker”,其它步骤和上面创建服务器端一样。

2、修改配置application.yml

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

3、添加控制器 InvokerController.java

package com.example.firstcloudinvoker;

import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate; @RestController
@Configuration
public class InvokerController {
@Bean
@LoadBalanced
public RestTemplate getRestTemplate(){
return new RestTemplate();
} @RequestMapping(value = "/router", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
public String router(){
RestTemplate restTpl = getRestTemplate();
//根据应用名称调用服务
String json = restTpl.getForObject("http://first-cloud-provider/user/1", String.class);
return json;
}
}

4、修改启动类代码FirstCloudInvokerApplication.java

添加注解@EnableDiscoveryClient,使得服务调用者可以去Eureka中发现服务。

package com.example.firstcloudinvoker;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient; @SpringBootApplication
@EnableDiscoveryClient
public class FirstCloudInvokerApplication { public static void main(String[] args) {
SpringApplication.run(FirstCloudInvokerApplication.class, args);
} }

四、编写REST客户端进行测试

1、创建项目

IDEA中创建一个新的SpringBoot项目,名称为“first-cloud-rest-client”,SpringBoot版本选择2.1.9,在选择Dependencies(依赖)的界面勾选Web->Spring Web。
在pom.xml中增加httpclient依赖。

<?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.9.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.example</groupId>
<artifactId>first-cloud-rest-client</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>first-cloud-rest-client</name>
<description>Demo project for Spring Boot</description> <properties>
<java.version>1.8</java.version>
</properties> <dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency> <dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency> <dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
</dependency>
</dependencies> <build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build> </project>

2、修改配置application.yml

server:
port: 9001

3、修改启动类代码FirstCloudRestClientApplication.java

编写调用REST服务的代码

package com.example.firstcloudrestclient;

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;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController; @SpringBootApplication
@RestController
public class FirstCloudRestClientApplication { public static void main(String[] args) {
SpringApplication.run(FirstCloudRestClientApplication.class, args);
} @RequestMapping("/")
public String testHttpClient(){
StringBuilder sb = new StringBuilder();
try{
CloseableHttpClient httpClient = HttpClients.createDefault();
for(int i=0;i<10;i++){
HttpGet httpGet = new HttpGet("http://localhost:9000/router");
HttpResponse response = httpClient.execute(httpGet);
sb.append(EntityUtils.toString(response.getEntity()) + "<br />");
}
}catch(Exception ex){
return ex.getMessage();
}
return sb.toString();
}
}

4、测试

(1)启动两个服务器端,在控制台中分别输入slave1和slave2启动。
(2)启动两个服务提供者,在控制台中分别输入8763和8764启动。
(3)启动服务调用者。
(4)启动REST客户端。

浏览器访问 http://slave1:8761/,页面如下

浏览器访问 http://slave2:8762/,页面如下

浏览器访问 http://localhost:8763/user/1,页面输出:

{"id":1,"name":"gdjlc","message":"http://localhost:8763/user/1"}

浏览器访问 http://localhost:8764/user/1,页面输出:

{"id":1,"name":"gdjlc","message":"http://localhost:8764/user/1"}

浏览器访问 http://localhost:9000/router,多次刷新页面,页面输出在8763和8764切换:

{"id":1,"name":"gdjlc","message":"http://localhost:8763/user/1"}
{"id":1,"name":"gdjlc","message":"http://localhost:8764/user/1"}

浏览器访问 http://localhost:9001/,页面输出

{"id":1,"name":"gdjlc","message":"http://localhost:8764/user/1"}
{"id":1,"name":"gdjlc","message":"http://localhost:8763/user/1"}
{"id":1,"name":"gdjlc","message":"http://localhost:8764/user/1"}
{"id":1,"name":"gdjlc","message":"http://localhost:8763/user/1"}
{"id":1,"name":"gdjlc","message":"http://localhost:8764/user/1"}
{"id":1,"name":"gdjlc","message":"http://localhost:8763/user/1"}
{"id":1,"name":"gdjlc","message":"http://localhost:8764/user/1"}
{"id":1,"name":"gdjlc","message":"http://localhost:8763/user/1"}
{"id":1,"name":"gdjlc","message":"http://localhost:8764/user/1"}
{"id":1,"name":"gdjlc","message":"http://localhost:8763/user/1"}

请求了10次,8763和8764分别被请求5次,可见已经达到负载均衡。

SpringCloud之Eureka:集群搭建的更多相关文章

  1. SpringCloud学习之—Eureka集群搭建

    Eureka集群的搭建 上次说过了在SpringCloud应用中使用Eureka注册中心,用来对服务提供者进行服务注册与发现,但同时,它也是一个"微服务",单个应用使用空间有限,因 ...

  2. SpringCloud之Eureka集群

    前面我们介绍了SpringCloud注册中心Eureka,但是存在一个单点故障的问题,一个注册中心远远不能满足实际的生产环境,现在我们介绍一下如何搭建一个Eureka集群. 一:集群环境搭建 我们先建 ...

  3. F版本SpringCloud 5—Eureka集群和自我保护机制

    源码地址:https://gitee.com/bingqilinpeishenme/Java-Tutorials 前言 上篇文章中,通过代码搭建了Eureka注册中心和客户端,是Eureka的简单应用 ...

  4. 微服务架构:Eureka集群搭建

    版权声明:本文为博主原创文章,转载请注明出处,欢迎交流学习! 服务注册.发现是微服务架构的关键原理之一,由于微服务架构是由一系列职责单一的细粒度服务构成的网状结构,服务之间通过轻量机制进行通信,这就必 ...

  5. Eureka集群搭建

    服务注册.发现是微服务架构的关键原理之一,由于微服务架构是由一系列职责单一的细粒度服务构成的网状结构,服务之间通过轻量机制进行通信,这就必然引入一个服务注册发现的问题,也就是说服务提供方要注册报告服务 ...

  6. 三(2)、springcloud之Eureka集群配置

    1)原理说明** 服务启动后向Eureka注册,Eureka Server会将注册信息向其他Eureka Server进行同步,当服务消费者要调用服务提供者,则向服务注册中心获取服务提供者地址,然后会 ...

  7. Spring Cloud Eureka 集群搭建 - 以及发现一个 “直觉BUG”

    首先解释一下标题所说的“直觉BUG”,这个是我自己的定义.就是我们直觉上认为这是一个BUG,是一个错误,而实际并没有出错. 比如下图: 虽然出现报错信息,但是,整个程序并没有出错.至于原因,图片上的文 ...

  8. 十六、springcloud(二)Eureka集群

    1.创建子工程spring-cloud-peer(jar) 2.创建application-peer1.properties,application-peer2.properties applicat ...

  9. springcloud中eureka集群unavailable-replicas

    unavailable-replicas 配置了集群,但是在注册中心显示另外的几个集群地址是不可用的: 1 首先需要再host中添加服务名映射,如果应映射了再看是否在yml中配置了prefer-ip- ...

  10. springcloud(三) eureka集群

    上一节讲到user微服务和order微服务和eureka注册中心一起使用,那么问题来了如何注册中心挂了怎么办?ok, 注册中心集群就来了. 原理图: 注意euraka 之间是通过复制(replicat ...

随机推荐

  1. Java并发编程学习随笔 (一) 使用run() 和 start()的差别

    java多线程run()和start()的区别 当你启动线程,使用start(),系统会把run()方法当成线程执行体来处理,这是正常的,也是正确的情况.但是,当你启动线程时,调用run()方法,系统 ...

  2. [TimLinux] python-ldap 介绍

    1. 接口 ldap: LDAP库接口 ldap.asyncsearch: 大量搜索结果数据采用流处理 ldap.controls: LDAPv3上层访问扩展控制 ldap.dn: LDAP dist ...

  3. [Python Basics]下划线变量

    夜暗归云绕柁牙,江涵星影鹭眠沙. 行人怅望苏台柳,曾与吴王扫落花. 我平时很常见到的带有下划线的python变量有两种: 前后双下划线,我之前的理解是python程序中的类似meta data的信息, ...

  4. 微信小程序使用pako.js的踩坑笔记

    问题 今天组长跟我们讨论了个问题,说是文章存储占用有点大,消耗宽带流量费,让我看看能不能找个方法解决一下(文章存储的是html字符串).第一反应是没什么头绪,能想到的就是将相同的字符串替换成一个标识之 ...

  5. Jquery判断当前时PC端,移动端,平板端屏幕

    $(function(){     // console.log(navigator.userAgent);     var os = function (){       var ua = navi ...

  6. PHP 7.4.0发布!一起看看有哪些新特性

    PHP 7.4.0 发布了,此版本标志着 PHP 7 系列的第四次特性更新. 看了英文手册后,发现其进行了许多改进,并带来了一些新特性,现在将这些新特性您: 1.Typed Properties 类型 ...

  7. ES7中的async 和 await

    async 和 await 一个函数如果加上 async ,那么该函数就会返回一个 Promise async function test() { return "1" } con ...

  8. 【MyBatis】ResultMap

    [MyBatis]ResultMap 转载:https://www.cnblogs.com/yangchongxing/p/10486854.html 支持的 JDBC 类型为了未来的参考,MyBat ...

  9. 【Java Web开发学习】Spring JPA

    [Java Web开发学习]Spring JPA 转载:https://www.cnblogs.com/yangchongxing/p/10082864.html 1.使用容器管理类型的JPA JND ...

  10. before和after的操作

    before和after,前者是在元素之前插入东西,后者是在元素后面插入东西,但插入的东西不仅仅只是文字而已,还有图标,以及计算器的操作. 由于两者的操作基本一样,这里以before为例 插入文字 & ...