配置nacos目的就是为了实现动态路由,按照服务名路由到对应的服务地址下。
首先需要在官网下载一个nacos 2.0.3,nacos下载安装配置可见我另一个文章,链接https://blog.csdn.net/qq_28147821/article/details/122301155?spm=1001.2014.3001.5502
配置好后,我将nacos的默认端口改为了8840,可以不做修改使用默认即可
配置好后,启动nacos,打开nacos的bin目录,右边以管理员运行startup.cmd,如下图所示表示运行成功。
使用idea创建一个空的maven项目hscprovider,搭建完成后删除src文件夹。
然后分别创建4个Spring Initializr项目,如下图所示,分别命名为gateway、gateway1和provider1、provider2.
将配置文件重命名为bootstrap.yml 并配置gateway和nacos
配置pom文件,特别注意版本问题,版本要一致,不然会有各种问题,我这边gateway和springboot用的2.0.4,还有就是在pom文件中、以及Dependencies下都要删掉原有的 spring-boot-starter-web 不然会报错。
4.0.0
org.springframework.boot
spring-boot-starter-parent
2.0.4.RELEASE
com.cnki
gateway2
0.0.1-SNAPSHOT
gateway2
Demo project for Spring Boot
1.8
org.springframework.boot
spring-boot-starter
org.springframework.boot
spring-boot-starter-test
test
org.springframework.cloud
spring-cloud-context
2.0.4.RELEASE
com.alibaba.cloud
spring-cloud-starter-alibaba-nacos-discovery
2.0.4.RELEASE
com.alibaba.cloud
spring-cloud-starter-alibaba-nacos-config
2.0.4.RELEASE
org.springframework.cloud
spring-cloud-starter-gateway
2.0.4.RELEASE
org.springframework.boot
spring-boot-maven-plugin
我们将gateway端口设置为8030 gateway1端口设置为8040 其他部分代码都一样
server:
port: 8040 #端口
spring:
application:
name: gateway-hsc #网关名称 用于显示在nacos的名称 两个网关名称一致
cloud:
nacos:
config:
file-extension: yml
server-addr: 127.0.0.1:8840 #nacos地址 配置中心
discovery:
server-addr: 127.0.0.1:8840 #nacos地址 注册中心
gateway:
discovery:
locator:
enabled: true #开启按照服务名寻址,负载均衡
#getway http://localhost:8030/providerhsc/provider/get 请求路径
lower-case-service-id: true
routes:
- id: nacos-getway-provider
uri: lb://providerhsc #路由地址
predicates:
- Path=/provider/** #断言
filters:
- StripPrefix=1
geteway启动类:
package com.cnki.gateway;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
@SpringBootApplication
@EnableDiscoveryClient //注册到nacos
public class GatewayApplication {
public static void main(String[] args) {
SpringApplication.run(GatewayApplication.class, args);
}
}
接下来就是配置服务提供者了,就是我们的具体的微服务。
provider1和provider2 代码都一样,除了端口号,我这边配置的provider1是8032 provider2是8033。
配置pom文件
4.0.0
org.springframework.boot
spring-boot-starter-parent
2.0.4.RELEASE
com.cnki
provider1
0.0.1-SNAPSHOT
provider1
Demo project for Spring Boot
1.8
org.springframework.boot
spring-boot-starter
org.springframework.boot
spring-boot-starter-test
test
com.alibaba.cloud
spring-cloud-starter-alibaba-nacos-discovery
2.0.3.RELEASE
com.alibaba.cloud
spring-cloud-starter-alibaba-nacos-config
2.0.3.RELEASE
org.springframework.boot
spring-boot-starter-web
org.springframework.boot
spring-boot-starter-web
2.6.3
compile
org.springframework.boot
spring-boot-maven-plugin
配置yml文件:这里的name就是你的服务名称providerhsc,需要配置在gateway的yml文件中
server:
port: 8033
spring:
application:
name: providerhsc
cloud:
nacos:
discovery:
server-addr: 127.0.0.1:8840
config:
server-addr: 127.0.0.1:8840
file-extension: yml
配置启动类Provider1Application :
package com.cnki.provider1;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class Provider1Application {
public static void main(String[] args) {
SpringApplication.run(Provider1Application.class, args);
}
}
创建控制器ProviderController 这里为了区分,我将return信息设置成“这是程序1”和“这是程序2”
package com.cnki.provider1.controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("provider/")
public class ProviderController {
@RequestMapping(value = "get", method = RequestMethod.GET)
public String getStr() {
return "这是程序1";
}
}
配置nginx config
upstream gateway {
server 127.0.0.1:8030;
server 127.0.0.1:8040;
}
server {
listen 80; #nginx默认端口
server_name gateway.com; #访问域名
#charset koi8-r;
#access_log logs/host.access.log main;
location / {
proxy_pass http://gateway;
}
配置本地host C:\Windows\System32\drivers\etc\hosts
127.0.0.1 gateway.com
就是本地访问该域名,默认访问127.0.0.1
然后启动nginx,双击nginx.exe
差不多就配置完成了。接下来进行测试。
启动gateway、gateway1、provider1和provider2
接下来就进行测试。
1、首先直接测试provider1和provider2 两个服务的地址分别是http://localhost:8032/provider/get 和http://localhost:8033/provider/get
2、测试gateway1和gateway
http://localhost:8040/providerhsc/provider/get
http://localhost:8030/providerhsc/provider/get
多次刷新,循环调用provider1和provider2 gateway自动实现了轮询。
3.测试nginx,统一前端入口,测试gateway负载轮询 浏览器输入地址:
http://gateway.com/providerhsc/provider/get
测试结果如下:实现了gateway的集群部署
接下来,我们程序中停止provider1,然后我们再请求
出现报错,这时候表示nacos并没有及时发现provider1已经停止了。
过了几秒钟,然后我们一直请求,程序一直就请求provider2了,表示nacos已经将provider1下线了,并不会去请求provider1了。
然后我们将provider1启动, 一直请求,过了大概5秒钟,系统又开始调用provider1了,表示,nacos自动识别provider1已经启动了。
然后我们又将gateway1停止,系统还是会请求gateway1,造成一直转圈,然后就请求成功,表明nginx去调用gateway1,请求一直没返回,然后nginx就会去调用gateway2,并完成所有请求。
这里存在一个问题,就是nginx并不知道gateway1已经挂掉,所以后面的请求都有可能去调用gatewaty1,造成请求时间过长。这个问题后面我再研究怎么处理。