W3Schools Learner's Blog

w3Schools programming knowledge summary website

div

7/06/2019

Spring Cloud客户端与服务器端集群详解,以及Ribbon整合

Spring Cloud是一个类似于dobbo的服务治理框架,将一个大项目拆分成N多个模块(也叫服务)开发部署,然后注册到Spring Cloud Eureka Server里面来,由Spring Cloud Eureka Server注册中心统一进行管理,所以局部的崩溃不会引起整个项目的使用,Spring Cloud项目具有高可用,负载均衡的好处,因此深受许多公司的喜爱。
下面小编将来介绍一下Spring Cloud客户端与服务器端集群的示例,让大家体会一下Spring Cloud的好处,下图介绍的是:
当一个用户通过浏览器或APP访问后端的时候,首先通过的是Ribbon负载均衡模块从Spring Cloud Eureka Server服务端中获取Spring Cloud Eureka Client的数据,Spring Cloud Eureka Client客户端的作用主要就是从数据库中获取一些数据,或者将数据存储到数据库中,里面定义的是一些接口。
为什么Ribbon可以从Server服务端中获取到Client客户端中的数据呢?
因为Spring Cloud Ribbon与Spring Cloud Eureka Client都注册到了Server服务端中了,所以他们就可以通过Server查找到Client中的接口,并进行调用。
Server注册中心与Client做集群有什么好处呢?
好处就是,当任何一个server或者client客户端崩溃了或网络断掉,由于Ribbon的负载均衡作用,能自主选择剩余能运行的服务,用户或APP就能继续正常的访问网页,而不至于断掉。
如图所示:

下面来开始实现Spring Cloud客户端与服务器端集群,并通过Ribbon来调用Client中定义的接口,在此之前,小编创建了5个项目,两个Client客户端,它们的代码一模一样;两个Server服务端,代码也一模一样;一个Ribbon消费端,用于调用client端接口,创建的都是JAVA应用,而不是WEB应用,如图。

一、引入JAR包

这5个项目引入的jar包都是一样的,因为他们包含了所有Spring Cloud所需要的jar包,后面步骤中将不再介绍引入jar包的事情,方法是:在pom.xml文件的<project>标签内部引入cloud相关的maven jar包,代码如下:
<parent>
 <groupId>org.springframework.boot</groupId>
 <artifactId>spring-boot-starter-parent</artifactId>
 <version>2.0.5.RELEASE</version>
 <relativePath/> <!-- lookup parent from repository -->
</parent>

<properties>
 <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
 <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
 <java.version>1.8</java.version>
 <spring-cloud.version>Finchley.SR1</spring-cloud.version>
</properties>

<dependencies>
 <dependency>
  <groupId>org.springframework.cloud</groupId>
  <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
 </dependency>

 <dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-test</artifactId>
  <scope>test</scope>
 </dependency>
</dependencies>

<dependencyManagement>
 <dependencies>
  <dependency>
   <groupId>org.springframework.cloud</groupId>
   <artifactId>spring-cloud-dependencies</artifactId>
   <version>${spring-cloud.version}</version>
   <type>pom</type>
   <scope>import</scope>
  </dependency>
 </dependencies>
</dependencyManagement>

<build>
 <plugins>
  <plugin>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-maven-plugin</artifactId>
  </plugin>
 </plugins>
</build>

二、创建两个Spring Cloud Eureka Server服务注册中心的Java Maven项目

这两个项目的java Main方法代码是一样的它们需要相互注册到对方的服务注册中心去(上图有画出),唯一不一样的就是application.properties中的配置不太一样,比如端口,以及“defaultZone”指向的注册地址,端口号分别为:8760与8761。

2.1 Server 1,服务注册中心(一)的代码及配置

一:Java类的Main方法,代码如下:
package com.tpyyes;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;

@EnableEurekaServer
@SpringBootApplication
public class EurekaServerOneApplication {

 public static void main(String[] args) {
  SpringApplication.run(EurekaServerOneApplication.class, args);

 }

}
二:application.properties的配置文件代码如下:
# Server 1端口
server.port=8760
# Server 1的应用名称
spring.application.name=eureka
# 关闭自我保护机制,并5秒钟检查一次服务列表,如果client服务关闭,则从列表中清理掉
eureka.server.enable-self-preservation=false
eureka.server.eviction-interval-timer-in-ms=5000
eureka.client.register-with-eureka=false
eureka.client.fetch-registry=false
# 注册到Server 2中 
eureka.client.serviceUrl.defaultZone: http://localhost:8761/eureka/

2.2 Server 2,服务注册中心(二)的代码及配置

一:Java类的Main方法,代码如下:
package com.tpyyes;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;

@EnableEurekaServer
@SpringBootApplication
public class EurekaServerTwoApplication {

 public static void main(String[] args) {
  SpringApplication.run(EurekaServerTwoApplication.class, args);

 }

}
二:application.properties的配置文件代码如下:
# Server 2端口
server.port=8761
# Server 2的应用名称
spring.application.name=eureka
# 关闭自我保护机制,并5秒钟检查一次服务列表,如果client服务关闭,则从列表中清理掉
eureka.server.enable-self-preservation=false
eureka.server.eviction-interval-timer-in-ms=5000
eureka.client.register-with-eureka=false
eureka.client.fetch-registry=false
# 注册到Server 1中 
eureka.client.serviceUrl.defaultZone: http://localhost:8760/eureka/

2.3 运行两个Server服务注册中心

分别运行Server 1与Server 2,效果如图所示,可以相互看到对方的注册中心链接:

三、创建两个Spring Cloud Eureka Client客户端

这两个项目的客户端的Java代码一样,就是properties配置不一样,这两个客户端都需要分别注册到上面两个Server注册中心中去,小编用的端口分别为:8888与9999。

3.1 Client 1,客户端(一)的代码及配置

一:客户端Java类的Main方法,启动之后访问接口会输出String字符串,代码如下:
package com.tpyyes;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@EnableEurekaClient
@SpringBootApplication
public class EurekaClientOneApplication {

 public static void main(String[] args) {
  SpringApplication.run(EurekaClientOneApplication.class, args);

 }

}

@RestController
class ServiceInstanceRestController {

    @RequestMapping("/api/hello")
    public String welcome() {
        return "hello world spring cloud client";
    }
}
二:客户端application.properties的配置文件代码如下:
# 客户端1端口
server.port=8888
# 客户端1应用名称,要与客户端2名称一致
spring.application.name=eureka-client
eureka.instance.preferIpAddress=true
# 开启健康检查(需要spring-boot-starter-actuator依赖,本项目已经有了),10秒向Server汇报一次
eureka.client.healthcheck.enabled = true
eureka.instance.lease-renewal-interval-in-seconds =10
eureka.instance.lease-expiration-duration-in-seconds =30
# client 1分别注册到两个Server注册中心中
eureka.client.serviceUrl.defaultZone: http://localhost:8760/eureka/,http://localhost:8761/eureka/

3.2 Client 2,客户端(二)的代码及配置

一:客户端Java类的Main方法,启动之后访问接口会输出String字符串,代码如下:
package com.tpyyes;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@EnableEurekaClient
@SpringBootApplication
public class EurekaClientTwoApplication {

 public static void main(String[] args) {
  SpringApplication.run(EurekaClientTwoApplication.class, args);

 }

}

@RestController
class ServiceInstanceRestController {

    @RequestMapping("/api/hello")
    public String welcome() {
        return "hello world spring cloud client";
    }
}
二:客户端application.properties的配置文件代码如下:
# 客户端2端口
server.port=9999
# 客户端2应用名称,要与客户端1名称一致
spring.application.name=eureka-client
eureka.instance.preferIpAddress=true
# 开启健康检查(需要spring-boot-starter-actuator依赖,本项目已经有了),10秒向Server汇报一次
eureka.client.healthcheck.enabled = true
eureka.instance.lease-renewal-interval-in-seconds =10
eureka.instance.lease-expiration-duration-in-seconds =30
# client 2分别注册到两个Server注册中心中
eureka.client.serviceUrl.defaultZone: http://localhost:8760/eureka/,http://localhost:8761/eureka/

3.3 运行两个客户端

分别运行客户端1与客户端2的main方法,可以在server 1与server 2中分别都能看到两个客户端注册进来的地址,如图:

最后,当我们访问“http://localhost:8888/api/hello”或“http://localhost:9999/api/hello”,两个都能输出如下的“hello world spring cloud client”字符串信息:

备注说明:
经过上方的三个步骤,可以说明我们的两个Client客户端都已经成功的注册到了两个注册中心中,这两个Server注册中心之间也形成了相互注册,此时还需要使用Ribbon进行负载均衡,也就是说你随意关闭两个Server注册中心或Client客户端中的一个,我们在访问接口的时候,依然能输出“hello world spring cloud client”字符串。

四、使用Spring Cloud Eureka Ribbon负载均衡

我们还需要写一个Ribbon应用,实现Spring Cloud负载均衡,当我们访问接口时,不仅能均匀分配客户端的访问压力,还能在客户端出问题时应用依然能正常运行,因此小编将该应用的端口设置为8080,Ribbon也需要注册到两个Server服务注册中心里面去。

4.1 Ribbon应用的代码及配置

一:Ribbon的Java代码如下,“@LoadBalanced”为负载均衡注解,:
package com.tpyyes;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.context.annotation.Bean;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

@EnableEurekaClient
@SpringBootApplication
public class EurekaRibbonApplication {

 public static void main(String[] args) {
  SpringApplication.run(EurekaRibbonApplication.class, args);

 }
 
    @Bean
    @LoadBalanced
    public RestTemplate getRestTemplate() {
        return new RestTemplate();
    }

}

@RestController
class ServiceInstanceRestController {
 
 @Autowired
 private RestTemplate getRestTemplate;

    @RequestMapping("/api/getInfo")
    public String welcome() {
        // 客户端应用名称
     String serviceId = "eureka-client";
        String res = getRestTemplate.getForObject("http://"+serviceId+"/api/hello", String.class);
        return "Client客户端返回的结果是:"+res;
    }
}
二:Ribbon应用application.properties的配置文件代码如下:
# Ribbon应用端口
server.port=8080
# Ribbon应用名称
spring.application.name=eureka-ribbon-api
eureka.instance.preferIpAddress=false
ping-server.ribbon.eureka.enabled=false
# 注册到服务注册中心列表中
ping-server.ribbon.eureka.listOfServers=http://localhost:8760/eureka/,http://localhost:8761/eureka/
ping-server.ribbon.eureka.ServerListRefreshInterval=3600

4.2 运行Ribbon应用

运行Ribbon应用之后,可以分别在两个Server注册中心中看到Ribbon的应用已经被注册了,如图:

当我们访问“http://localhost:8080/api/getInfo”时,就能均衡调用两个Client客户端应用,并输出Client里面获取的字符串信息了,如图:

集群整合完毕!

No comments:

Post a Comment

Note: only a member of this blog may post a comment.