一起来学Spring Cloud | 第二章:服务注册和发现组件 (Eureka)
一、负载均衡的简介:
负载均衡是高可用架构的一个关键组件,主要用来提高性能和可用性,通过负载均衡将流量分发到多个服务器,多服务器能够消除单个服务器的故障,减轻单个服务器的访问压力。
1、服务端负载均衡:客户端请求到负载均衡服务器,负载均衡服务器根据自身的算法将该请求转给某台真正提供业务的服务器,该服务器将响应数据给负载均衡服务器,负载均衡服务器最后将数据返回给客服端,服务端负载均衡完全由服务器处理,客户端不需要做任何事情。常见例子,例如:nginx
2、客服端负载均衡:基于客户端的负载均衡,简单的说就是在客户端程序里面,维护一组服务器引用,自己设定一个调度算法,在向服务器发起请求的时候,先执行调度算法计算出向哪台服务器发起请求,然后再发起请求给服务器,常见例子,例如:ribbon
二、ribbon的简介:
上一篇文章,讲了服务的注册和发现。在微服务架构中,业务都会被拆分成一个独立的服务,服务与服务的通讯是基于http restful的。spring cloud提供两种服务调度方式,一种方式是ribbon+resttemplate,另一种方式是feign。这章先讲解下基于ribbon+restful的服务请求方式。
ribbon是一个负载均衡客户端,提供了很多在http和tcp客户端之上的控制。feign内部也已经使用了ribbon, 所以只要使用了@feignclient注解,也能实现本章功能。
三、准备集群服务:
通过标题我们也知道ribbon有负载均衡的功能,所以首先需要准备一个服务器集群。这一篇文章基于上一篇文章的工程,继续进行完善的。
有些功能的命名及新增springcloud模块,不太清楚的同学,可以参考:第二章:服务注册和发现组件 (eureka)
1. 启动eureka-server 工程,eureka注册中心就启动了。
2. 启动springcloud-eureka-client工程,上篇文章我们知道springcloud-eureka-client工程的端口为9300。
3. 将springcloud-eureka-client工程的端口改成9400(修改application.properties文件),然后再启动springcloud-eureka-client。
通过上面三个步骤,我们就相当于在eureka服务上启动了两个springcloud-eureka-client服务,但是端口号不同,输入 http://localhost:8761/ 查看页面效果
四、新建ribbon客户端模块:
重新新建一个spring-boot工程,取名为:springcloud-ribbon-client
1. 修改pom.xml文件(parent标签的内容引入的是第二章创建的父pom,后续新建的模块都会引用。然后在父pom的<modules>标签中加入 <module>springcloud-ribbon-client</module>配置,将新建的模块依赖到父模块。
ps:有些同学没有按照顺序来,自己在parent标签中,直接引入springboot的父pom,其实也可以,但是如果报错一定要注意,springboot的版本与springcloud的版本是否匹配。
我们父pom中springboot的版本号为: <version>2.1.4.release</version>,springcloud的版本号为: <spring-cloud.version>finchley.release</spring-cloud.version>
直接看本章,有不清楚的同学可以参考:一起来学spring cloud | 第二章:服务注册和发现组件 (eureka)
<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelversion>4.0.0</modelversion>
<parent>
<groupid>com.haly</groupid>
<artifactid>springcloud</artifactid>
<version>0.0.1-snapshot</version>
</parent>
<groupid>com.haly</groupid>
<artifactid>springcloud-ribbon-client</artifactid>
<version>0.0.1-snapshot</version>
<name>springcloud-ribbon-client</name>
<description>新建一个springcloud项目</description>
<dependencies>
<dependency>
<groupid>org.springframework.cloud</groupid>
<artifactid>spring-cloud-starter-netflix-eureka-client</artifactid>
</dependency>
<dependency>
<groupid>org.springframework.boot</groupid>
<artifactid>spring-boot-starter-web</artifactid>
</dependency>
<dependency>
<groupid>org.springframework.cloud</groupid>
<artifactid>spring-cloud-starter-netflix-ribbon</artifactid>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupid>org.springframework.boot</groupid>
<artifactid>spring-boot-maven-plugin</artifactid>
</plugin>
</plugins>
</build>
</project>
2. 修改springcloud-ribbon-client的配置文件application.properties
server.port=9500
spring.application.name=springcloud-ribbon-client
eureka.client.serviceurl.defaultzone=http://localhost:8761/eureka/
3. 在工程的启动类中,新增注解配置
@enablediscoveryclient向服务中心注册,并且注册了一个叫resttemplate的bean。
@ loadbalanced注解表明,这个restremplate是需要做负载均衡的。
package com.haly.springcloud;
import org.springframework.boot.springapplication;
import org.springframework.boot.autoconfigure.springbootapplication;
import org.springframework.cloud.client.discovery.enablediscoveryclient;
import org.springframework.cloud.client.loadbalancer.loadbalanced;
import org.springframework.context.annotation.bean;
import org.springframework.web.client.resttemplate;
@springbootapplication
@enablediscoveryclient
public class springcloudribbonclientapplication {
public static void main(string[] args) {
springapplication.run(springcloudribbonclientapplication.class, args);
}
@bean
@loadbalanced
resttemplate resttemplate() {
return new resttemplate();
}
}
4. 新建一个service类,用来调用第二章在springcloud-eureka-client模块中的hello方法,详情参考:一起来学spring cloud | 第二章:服务注册和发现组件 (eureka)
package com.haly.springcloud.service;
import org.springframework.beans.factory.annotation.autowired;
import org.springframework.stereotype.service;
import org.springframework.web.client.resttemplate;
@service
public class ribbonservice {
@autowired
resttemplate resttemplate;
public string gethello(string name) {
return resttemplate.getforobject("http://springcloud-eureka-client/hello?name="+name,string.class);
}
}
ps: 我们请求时用springcloud-eureka-client服务名代替了ip地址,在ribbon中它会根据服务名来选择具体的服务实例,根据服务实例在请求的时候会用具体的url替换掉服务名。
5. 新建一个controller名为:ribboncontroller,来接收浏览器访问,ribboncontroller的gethello方法调用ribbonservice的gethello方法
package com.haly.springcloud.controller;
import org.springframework.beans.factory.annotation.autowired;
import org.springframework.web.bind.annotation.getmapping;
import org.springframework.web.bind.annotation.requestparam;
import org.springframework.web.bind.annotation.restcontroller;
import com.haly.springcloud.service.ribbonservice;
@restcontroller
public class ribboncontroller {
@autowired
ribbonservice ribbonservice;
@getmapping(value = "/gethello")
public string gethello(@requestparam string name) {
return ribbonservice.gethello(name);
}
}
6. 打开浏览器输入http://localhost:9500/gethello?name=young码农 多次访问页面会交替出现如下结果
从上图可以验证,当我们通过调用resttemplate.getforobject("http://springcloud-eureka-client/hello?name="+name,string.class)方法时,已经做了负载均衡,访问了不同的端口的服务实例。
五、实验总结:
项目结构:
1. 一个服务注册中心,eureka server,端口为8761
2. springcloud-eureka-client工程跑了两个实例,端口分别为9300,9400,分别向服务注册中心注册
3. springcloud-ribbon-client端口为9500,向服务注册中心注册
4. 当springcloud-ribbon-client通过resttemplate调用springcloud-eureka-client的hello接口时,因为用ribbon进行了负载均衡,会轮流的9300和9400 两个服务端口的hello接口
推荐阅读