3-Spring cloud之搭建Ribbon负载均衡——服务器上实操(上)
- 1. 前言
- 2. ribbon整合eureka入门
- 2.1 修改相关配置
- 2.1.1 修改服务消费者pom,引入ribbon相关依赖
- 2.1.2 修改服务消费者yml,将客户端注册进eureka服务列表内
- 2.1.3 修改配置类,开启客户端的负载均衡
- 2.1.4 修改主启动类,开启客户端向注册中心eureka注册服务
- 2.1.5 修改客户端的访问类,消费者按名字访问微服务
- 2.2 启动服务,查看效果
- 3. 部署服务提供者到服务器上(单台)
- 3.1 修改数据库服务地址
- 3.2 修改Controller里的方法——为了测试
- 3.3 打包、启动问题
- 3.3.1 启动问题——no main manifest attribute
- 3.3.1.1 问题描述
- 3.3.1.2 解决问题
- 3.3.1.3 关于此问题详细解析
- 3.3.2 解决打出的jar包没有Java文件
- 3.4 启动、访问、看效果
- 3.4.1 启动
- 3.4.2 访问
- 3.4.2 访问问题
- 4. ribbon的负载均衡(之轮询)
- 4.1 在多台机器上部署服务提供者
- 4.1.1 注意修改yml配置文件
- 4.1.2 部署到3台服务器上
- 4.1 启动服务消费者
- 4.1.1 访问可能出现的问题
- 4.1.1.1 问题1:502 Bad Gateway
- 4.1.1.2 问题2:Operation timed out (Connection timed out)
- 4.1.1.2.1 问题描述
- 4.1.1.2.2 尝试排查问题
- 4.1.1.2.3 解决问题
- 4.1.1.2.4 重新启动服务看效果
- 4.1.2 问题解决后,重启各服务,观看轮询效果
- 4.2 ribbon负载均衡架构
1. 前言
- 本篇文章是继上篇eureka文章之后的更新,上篇文章如下:
1-Eureka服务注册与发现以及Eureka集群搭建(实操型).
2. ribbon整合eureka入门
- 在上篇文章的基础上,引入ribbon,让ribbon和eureka结合,实现消费者可以直接调用微服务,不用再管服务提供者的IP和端口号,具体操作请继续……
2.1 修改相关配置
2.1.1 修改服务消费者pom,引入ribbon相关依赖
- 如下:
<!--引入ribbon相关依赖,ribbon是客户端的负载均衡,ribbon需要和eureka整合--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-eureka</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-ribbon</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-config</artifactId> </dependency>
2.1.2 修改服务消费者yml,将客户端注册进eureka服务列表内
- 如下:
这里将register-with-eureka
不设置的话,默认是true,就是将消费者服务也注册到注册中心了,待会看效果spring: application: name: dog-consumer eureka: client: # 客户端注册进eureka服务列表内 # register-with-eureka: false # false表示不向注册中心注册自己 service-url: defaultZone: http://IP1:2886/eureka/,http://IP2:2886/eureka,http://IP3:2886/eureka/
2.1.3 修改配置类,开启客户端的负载均衡
- 如下,添加
@LoadBalanced
注解即可:
2.1.4 修改主启动类,开启客户端向注册中心eureka注册服务
- 添加开启注解,如下:
@EnableEurekaClient //开启客户端向注册中心eureka注册服务
2.1.5 修改客户端的访问类,消费者按名字访问微服务
- 修改,如下:
- 为什么写成大写的:
DOG-PROVIDER
,如下:
- 为什么写成大写的:
2.2 启动服务,查看效果
- 首先,启动
eureka集群
,我这边一直在服务器上跑着,没停的,本次也没修改,所以不用重新启动 - 然后启动服务提供者 和 服务消费者
- 最后观看效果,因为服务提供者也没有修改,所以主要观察服务消费者能否正常访问,以及eureka的注册情况,如下:
OK,没问题,ribbon与eureka整合没问题,可问题是,怎么体现负载均衡呢?请继续……
3. 部署服务提供者到服务器上(单台)
- 为了效果,这里直接在服务器上测试,首先先部署单台,改动点如下:
3.1 修改数据库服务地址
- 把之前localhost改成真实的IP,前提是安装了mysql,这个在这里就不多说了,如下
3.2 修改Controller里的方法——为了测试
- 为了后续的效果,这里将服务器IP返回前端,如下:
@RequestMapping(value = "/getDogByNum/{dogNum}",method = RequestMethod.GET) public Object getDogByNum(@PathVariable("dogNum") Long dogNum) throws UnknownHostException { Map<String, Object> resultMap = new HashMap<>(); InetAddress address = InetAddress.getLocalHost(); String ipAddress = address.getHostAddress(); System.out.println(ipAddress); resultMap.put("ipAddress",ipAddress); resultMap.put("dog",dogService.getDogByNum(dogNum)); return resultMap; }
3.3 打包、启动问题
3.3.1 启动问题——no main manifest attribute
3.3.1.1 问题描述
- 问题如下:
no main manifest attribute, in dog-provider-8001-1.0-SNAPSHOT.jar
3.3.1.2 解决问题
- 解决问题如下:
在该微服务(工程的对应子模块——微服务提供者)的pom文件里添加,如下配置,注意是子模块里,不是父工程的pom文件里,如下:
<build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <version>${spring-boot.version}</version> <configuration> <mainClass>com.liu.susu.DogProviderApp8001</mainClass> </configuration> <executions> <execution> <goals> <goal>repackage</goal> </goals> </execution> </executions> </plugin> </plugins> </build>
- 再次启动
3.3.1.3 关于此问题详细解析
- 可以参考下面的文章:
解决no main manifest attribute, in XXX.jar.
3.3.2 解决打出的jar包没有Java文件
- 解决问题,如下
在父工程的pom文件里添加如下配置即可:<!--解决 打出的jar包里没有Java文件--> <resource> <directory>src/main/java</directory> <filtering>true</filtering> <includes> <include>**/*.java</include> </includes> </resource>
3.4 启动、访问、看效果
3.4.1 启动
- 好了使用简单脚本启动,如下:
#!/bin/bash JAVA_HOME=$JAVA_HOME nohup java -XX:+UseG1GC -XX:+HeapDumpOnOutOfMemoryError -Xms512M -Xmx4G -jar dog-provider-8001-1.0-SNAPSHOT.jar -XX:-OmitStackTraceInFastThrow > /dev/null 2>&1 &
- 启动、查看进程
sh startServer.sh ps -ef | grep java
3.4.2 访问
3.4.2 访问问题
- 好了,启动完成之后,就可以访问了,访问可以访问,但是IP有点问题,如下:
- 怎么让IP显示成服务器的公网IP呢?将controller里的代码改一下即可,如下:
-
修改代码
@RequestMapping(value = "/getDogByNum/{dogNum}",method = RequestMethod.GET) public Object getDogByNum(@PathVariable("dogNum") Long dogNum) throws UnknownHostException { Map<String, Object> resultMap = new HashMap<>(); InetAddress address = InetAddress.getLocalHost(); String hostName = address.getHostName(); System.out.println(getHostName); HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest(); StringBuffer ipAddressStr = new StringBuffer(); ipAddressStr.append(request.getScheme() + "://"); ipAddressStr.append(request.getServerName() + ":"); ipAddressStr.append(request.getServerPort() + ""); ipAddressStr.append(request.getContextPath() + "/"); System.out.println(ipAddressStr); resultMap.put("hostName",hostName); resultMap.put("ipAddress",ipAddressStr); resultMap.put("dog",dogService.getDogByNum(dogNum)); return resultMap; }
- 再次启动看效果,如下:
- 再次启动看效果,如下:
-
4. ribbon的负载均衡(之轮询)
4.1 在多台机器上部署服务提供者
4.1.1 注意修改yml配置文件
- 3个服务上3个文件不同,不同说了,如下是注意点:
- 第一点,记得要根据机器换不同的配置文件,这里是3台,112,142,175:
spring: profiles: active: 112
- 第二点,注意3台上配置的 instance-id 不能一样,否则eureka注册不上,如下:
- 第一点,记得要根据机器换不同的配置文件,这里是3台,112,142,175:
4.1.2 部署到3台服务器上
- 将服务提供者部署到3台服务器上,用同样的方法把两外两台也部署上即可,并确保可以访问,如下:
-
查看eureka注册情况,确保3台微服务都注册上来
-
并确保3台机器上是否可以独立访问:
-
4.1 启动服务消费者
4.1.1 访问可能出现的问题
4.1.1.1 问题1:502 Bad Gateway
- 问题描述:
我这里是本地启动的消费者服务,启动之后访问就报,502,如下:org.springframework.web.client.HttpServerErrorException: 502 Bad Gateway
- 问题原因:
上面已经测试本地启动没问题,怎么把服务提供者部署到服务器上之后,通过服务消费者就不能访问了呢,哦,后来才发现电脑上有代理,开着梯子呢,所以,记得关闭自己的梯子。 - 解决问题:
关了代理,重新访问。
4.1.1.2 问题2:Operation timed out (Connection timed out)
4.1.1.2.1 问题描述
- 问题描述如下:
Operation timed out (Connection timed out)
4.1.1.2.2 尝试排查问题
- 排查一:确保服务提供者能正常提供服务,没有宕机;
- 排查二:检查3台服务提供者的防火墙已经关闭;
- 排查三:本地
ping
看能否通ping ip telnet ip 8001
- 排查四:试试不用负载均衡
- 去掉开启负载均衡的注解
- controller中将地址写死
- 再看效果,发现可以访问(3个IP都没问题)
- 去掉开启负载均衡的注解
- 排查五:试试本地启动服务提供者(8001),服务器上的都停掉
- 带着负载均衡注解,如下:
- 访问试试,也没问题
那问题到底是什么呢?哦,原来是因为IP问题,怎么解决,继续……
- 带着负载均衡注解,如下:
4.1.1.2.3 解决问题
- 解决问题
- 在服务提供者的配置文件里添加如下配置即可解决(主要是配置IP),如下:
ip-address: 启动服务提供者的IP non-secure-port: 8001 # 可以不用配置
- 在服务提供者的配置文件里添加如下配置即可解决(主要是配置IP),如下:
4.1.1.2.4 重新启动服务看效果
- 先启动一台,如下:
可以通过消费者正常访问了,问题解决!
4.1.2 问题解决后,重启各服务,观看轮询效果
- 这次干脆直接部署4台,将4台微服务重新部署启动,如下:
- 通过服务消费者访问,如下:
http://localhost/consumer/dog/getDogByNum/1
如果部署上的话,可以简单多点几次,默认走负载均衡的是轮询机制。
4.2 ribbon负载均衡架构
- 上面的架构部署设计可以根据下图理解,如下:
- 简单解释一下:
- 当Ribbon和Eureka配合使用的时候,Ribbon可从Eureka Server中获取服务提供者地址列表,并基于负载均衡算法,请求其中一个服务提供者实例。
- 该结构包含一个Eureka服务器,4个服务提供者以及一个含有Ribbon的服务消费者。4个服务提供者向Eureka服务器注册服务,当多个URL向服务消费者发起请求时,基于Ribbon的负载均衡器能够有效地将请求分摊到不同的机器上。