Spring Cloud服务管理框架Eureka项目集群(四)

紧跟上一篇博客,这里采用的也是上一篇博客的代码作为分析:Spring Cloud服务管理框架Eureka简单示例(三)。我们在搭建起了简单的单机模式Eureka项目之后,如果Eureka服务器和客户端不能满足高并发访问,项目需要集群部署,也可以利用Eureka做到这一点。我们这里创建两个Eureka服务器端,两个Eureka客户端(作为服务提供者),一个Eureka客户端(作为服务调用者),如图:

通过运行多个实例并让它们彼此注册,Eureka可以变得更有弹性和可用性。实际上,这是默认行为,所以需要做的就是将一个有效的serviceUrl添加到对等点。我们可以将多个对等点添加到一个系统中,只要它们之间至少有一条边连接,它们就会同步这些注册。如果对等体在物理上是分开的(在数据中心或多个数据中心之间),那么系统就可以在原则上生存下来,以避免“大脑分裂”。由于资源限制,这里让服务运行在同一个主机上,通过修改hosts文件配置,模仿两个不同的主机。

搜素Windows的“记事本”应用,以管理员身份运行,文件-->打开,找到C:\Windows\System32\drivers\etc目录,打开里面的“hosts”文件,在文件末尾为自己的主机添加两个虚拟的域名:

127.0.0.1 peer1 peer2

创建两个Eureka服务器端

找到我们上一篇博客编写的eureka-server项目,修改application.yml文件,配置如下:

---
server:
  port: 8761
spring:
  profiles: peerA
  application:
    name: eureka-server-A
eureka:
  instance:
    hostname: peer1
  client:
    serviceUrl:
      defaultZone: http://peer2:8762/eureka/

---
server:
  port: 8762
spring:
  profiles: peerB
  application:
    name: eureka-server-B
eureka:
  instance:
    hostname: peer2
  client:
    serviceUrl:
      defaultZone: http://peer1:8761/eureka/

由于需要启动的是两个项目,所以这里配置一下两个项目的名称。再配置启动环境,方便我们作为项目的启动条件,打开ServerApp的class类,修改main方法,让系统读取我们输入在控制台的第一行,得到启动环境再启动:

package com.init.springCloud;

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 ServerApp {

	public static void main(String[] args) {
		@SuppressWarnings("resource")
		Scanner scan = new Scanner(System.in);
		String profiles = scan.nextLine();
		new SpringApplicationBuilder(ServerApp.class).profiles(profiles).run(args);
	}

}

之后运行ServerApp的main()方法,启动项目,在控制台输入“peerA”,回车,项目启动过程中会报错,但是不影响我们启动项目,报错的原因是eureka-server-A会将自己的服务注册到eureka-server-B,但是eureka-server-B还未启动,我们可以在浏览器访问http://localhost:8761,能够进入Eureka的后台管理界面,说明项目已经启动成功。再运行一次ServerApp的main()方法,在控制台输入“peerB”,回车,eureka-server-B项目是不会报错的,它能成功将自己注册到eureka-server-A。最后我们两个管理后台都能看见注册的服务信息:

创建两个Eureka客户端(提供者)

找到我们上一篇博客编写的eureka-provider,修改application.yml文件,为服务提供者再提供一个服务器端的注册地址,让我们的服务提供者可以将自己的服务注册到两个服务器端,配置如下:

spring:
  application:
    name: eureka-provider

eureka:
  client:
    serviceUrl:
      defaultZone: http://localhost:8761/eureka,http://localhost:8762/eureka

同样,为了模拟启用两个服务提供者,我们参照上面提供的方法,修改ProviderApp类的main()方法,让项目在启动的时候,读取输入的第一行,获取我们输入的端口号,根据输入端口的不同,启动两个不同的项目:

package com.init.springCloud;

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 ProviderApp {

	public static void main(String[] args) {
		@SuppressWarnings("resource")
		Scanner scan = new Scanner(System.in);
		String port = scan.nextLine();
		new SpringApplicationBuilder(ProviderApp.class).properties("server.port=" + port).run(args);
	}

}

为了能够让我们待会儿要创建的Eureka客户端(服务调用者)可以区分到底是从哪一个Eureka客户端(服务提供者)获取到返回值的,我们改造一下eureka-provider的Person类,为Person增加一个message属性,用以展示对应请求的路径(包含端口号),用端口号来鉴别调用的是哪一个服务:

package com.init.springCloud;

import lombok.Data;

@Data
public class Person {

	private Integer id;			//主键ID
	private String name;		//姓名
	private String message;		//信息
	
}

之后,为ProviderController类的searchPerson方法添加一个参数,传入请求信息,并把请求信息的URL设置到Person类的message属性里:

package com.init.springCloud;

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.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class ProviderController {

	@RequestMapping(value = "/search/{id}", method = RequestMethod.GET,produces = MediaType.APPLICATION_JSON_VALUE)
	@ResponseBody
	public Person searchPerson(@PathVariable Integer id,HttpServletRequest request){
		Person person = new Person();
		person.setId(id);
		person.setName("Spirit");
		person.setMessage(request.getRequestURL().toString());
		return person;
	}
	
}

运行ProviderApp类的main()方法,在控制台输入8080,启动第一个项目;然后再次运行ProviderApp类的main()方法,在控制台输入8081,启动第二个项目。项目成功启动之后,我们在浏览器分别访问http://localhost:8080/search/1和http://localhost:8081/search/1,能够得到对应的响应结果,如下:

 

然后访问我们的Eureka服务器端,http://localhost:8761或者http://localhost:8762,也能够看到服务被注册到了服务器端。

创建一个Eureka客户端(服务调用者)

找到我们上一篇博客编写的eureka-consumer,修改application.yml文件,为服务调用者再提供一个服务器端的注册地址,让我们的服务调用者可以将自己的服务注册到两个服务器端,再将端口修改了,避免冲突导致的不能启动项目,配置如下:

server:
  port: 9090

spring:
  application:
    name: eureka-consumer

eureka:
  client:
    serviceUrl:
      defaultZone: http://localhost:8761/eureka,http://localhost:8762/eureka

服务调用者需要的配置就完成了,然后我们运行ConsumerApp类的main()方法,成功启动之后,访问http://localhost:9090/router,反复刷新几次,可以看到,我们的服务调用者是依次去调用了8080和8081的服务,恰好每个服务轮询一次。

补充

1.Eureka客户端(服务调用者)的循环方式,用的是Ribbon的load balancers中Common rules的RoundRobinRule,这条规则只是简单地选择循环服务器,它通常被用作更高级规则的默认规则或回退。相关知识会在后续的博客中更新,读者也可以自己参照NetFlix的Ribbon相关资料进行学习。

2.我开篇给出的架构图中有提到,Eureka服务器端会将自己的服务注册列表复制给自己的集群Eureka服务器,那么意味着Eureka客户端(服务调用者)只需要将自己的服务注册到Eureka服务器A,Eureka服务器A就会把自己的服务列表同步到Eureka服务器B,Eureka服务器B也会得到Eureka客户端(服务调用者)的注册信息。问题来了,是否就等同于我上面的示例,只需要为Eureka客户端(服务调用者)配置一个服务注册地址就行了呢?其实不然,如果我配置的这个单一服务注册地址对应的机器没有宕掉,那还好说,万一我只注册到服务器A,服务器A又宕机了,在服务器B就不可能存在我的服务列表。所以,配置注册地址,有多少个服务器,就配置多少个注册地址。

源码点击这里

最后,大家有什么不懂的或者其他需要交流的内容,也可以进入我的QQ讨论群一起讨论:654331206

Spring Cloud系列:

Spring Cloud介绍与环境搭建(一)

Spring Boot的简单使用(二)

Spring Cloud服务管理框架Eureka简单示例(三)

Spring Cloud服务管理框架Eureka项目集群(四)

Spring Cloud之Eureka客户端健康检测(五)

Netflix之第一个Ribbon程序(六)

Ribbon负载均衡器详细介绍(七)

Spring Cloud中使用Ribbon(八)

具有负载均衡功能的RestTemplate底层原理(九)

OpenFeign之第一个Feign程序(十)

OpenFeign之feign使用简介(十一)

Spring Cloud中使用Feign(十二)

Netflix之第一个Hystrix程序(十三)

Netflix之Hystrix详细分析(十四)

Spring Cloud中使用Hystrix(十五)

Netflix之第一个Zuul程序(十六)

Spring Cloud集群中使用Zuul(十七)

Netflix之Zuul的进阶应用(十八)

消息驱动之背景概述(十九)

消息中间件之RabbitMQ入门讲解(二十)

消息中间件之Kafka入门讲解(二十一)

Spring Cloud整合RabbitMQ或Kafka消息驱动(二十二)

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值