springcloud使用alibaba的nacos注册中心,以及自定义ribbon使用

文章里将会讲到,如何部署nacos server服务,springcloud中如果使用,以及服务的负载均衡,自定义负载均衡规则等等。

现部署nacos server
这里我就直接部署单机的了,并连接mysql数据库作为数据源
这个是官方教程,以及nacos包下载地址,sql语句下载地址
https://nacos.io/zh-cn/docs/cluster-mode-quick-start.html

前提安装好mysql数据库,建议数据库安装5.7的版本,因为目前从git上面下载的nacos包对应的mysql版本就是5.7,最新的版本启动nacos server会报错

将下载的nacos_sql文件执行
这时候nacos_dectest数据库会新建一些表

再将nacos包下载下来并解压
修改conf/application.properties配置文件

# spring
server.contextPath=/nacos
server.servlet.contextPath=/nacos
server.port=8848

spring.datasource.platform=mysql

db.num=1
db.url.0=jdbc:mysql://127.0.0.1:3306/nacos_devtest?characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true
db.user=nacos_devtest
db.password=nacos

数据库地址用户名密码自己修改

下面就是启动nacos
进入到bin目录
sh startup.sh -m standalone

这时候观察启动日志

2019-11-20 13:28:45,066 INFO Tomcat started on port(s): 8848 (http) with context path '/nacos'
2019-11-20 13:28:45,076 INFO Nacos Log files: /Users/hucheng/workcode/java/springcloud-nacos-ribbon/nacos/logs/
2019-11-20 13:28:45,078 INFO Nacos Conf files: /Users/hucheng/workcode/java/springcloud-nacos-ribbon/nacos/conf/
2019-11-20 13:28:45,078 INFO Nacos Data files: /Users/hucheng/workcode/java/springcloud-nacos-ribbon/nacos/data/
2019-11-20 13:28:45,078 INFO Nacos started successfully in stand alone mode.
2019-11-20 13:28:45,832 INFO Initializing Servlet 'dispatcherServlet'
2019-11-20 13:28:45,854 INFO Completed initialization in 21 ms

看到以上日志就是启动成功了
这时候在浏览器中输入http://localhost:8848/nacos
就可以看到登陆界面了,输入用户名密码
nacos/nacos 默认的用户名密码

在这里插入图片描述
停掉nacos
sh shutdown.sh -m standalone


以上操作就是在本地部署单机nacos server服务了

下面就是springcloud如何使用,将服务注册到nacos
项目结构大概是
springcloud-nacos-ribbon-rest 消费者,也就是请求入口了
springcloud-nacos-ribbon-user 提供者,用户应用(双机)
springcloud-nacos-ribbon-order 提供者,订单应用

项目会使用springcloud feign调用
并在springcloud-nacos-ribbon-rest 消费者加上ribbon负载均衡,配合nacos手动可以调节权重

在这里插入图片描述
要使用nacos server注册中心的话需要引入以下包即可

<!-- nacos服务 -->
<dependency>
	<groupId>com.alibaba.cloud</groupId>
	<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
	<version>2.1.1.RELEASE</version>
</dependency>

整个项目结构
在这里插入图片描述
新建springcloud-nacos-ribbon-user项目根目录
pom.xml

<?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-instanc"
	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>

	<groupId>com.nacos.ribbon.user</groupId>
	<artifactId>springcloud-nacos-ribbon-user</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<packaging>pom</packaging>


	<name>springcloud-nacos-ribbon-user</name>
	<url>http://maven.apache.org</url>

	<modules>
		<module>springcloud-nacos-ribbon-user-api</module>
		<module>springcloud-nacos-ribbon-user-provider</module>
	</modules>

</project>

新建springcloud-nacos-ribbon-user-provider
pom.xml

<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>2.2.1.RELEASE</version>
		<relativePath /> <!-- lookup parent from repository -->
	</parent>
	<groupId>com.nacos.ribbon.user</groupId>
	<artifactId>springcloud-nacos-ribbon-user-provider</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<name>springcloud-nacos-ribbon-user-provider</name>
	<description>Demo project for Spring Boot</description>

	<properties>
		<java.version>1.8</java.version>
		<spring-cloud.version>Greenwich.SR1</spring-cloud.version>
	</properties>

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

		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-test</artifactId>
			<scope>test</scope>
			<exclusions>
				<exclusion>
					<groupId>org.junit.vintage</groupId>
					<artifactId>junit-vintage-engine</artifactId>
				</exclusion>
			</exclusions>
		</dependency>
		
		<dependency>
			<groupId>com.nacos.ribbon.user</groupId>	
			<artifactId>springcloud-nacos-ribbon-user-api</artifactId>
			<version>0.0.1-SNAPSHOT</version>
		</dependency>

		<!-- nacos服务 -->
		<dependency>
			<groupId>com.alibaba.cloud</groupId>
			<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
			<version>2.1.1.RELEASE</version>
		</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>

</project>

springcloud-nacos-ribbon-user-provider目录结构
在这里插入图片描述
启动类,Usercontroller,UserServiceImpl内容

@EnableDiscoveryClient
@SpringBootApplication
public class SpringcloudNacosRibbonUserProviderApplication {

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

}

@RequestMapping("user")
@RestController
public class UserController {
	
	@Autowired
	private UserService userService;
	
	@GetMapping("findUserByUserId")
	public String findUserByUserId(Long userId) {
		return userService.findUserByUserId(userId);
	}

}


@Service
public class UserServiceImpl implements UserService{
	
	@Value("${server.port}")
	private String port;

	@Override
	public String findUserByUserId(Long userId) {
		return "当前服务端口:"+port+",用户id:"+userId;
	}

}

application.properties内容

spring.application.name=springcloud-nacos-ribbon-user
server.port=18082
#注册服务到nacos server
spring.cloud.nacos.discovery.server-addr=127.0.0.1:8848

springcloud-nacos-ribbon-user-api项目结构
在这里插入图片描述
UserFeignClient,UserService内容

@FeignClient(name = "springcloud-nacos-ribbon-user")
public interface UserFeignClient {
	
	@GetMapping("/user/findUserByUserId")
	public String findUserByUserId(@RequestParam("userId") Long userId);
	
}

public interface UserService {
	
	public String findUserByUserId(Long userId);

}

上面整个springcloud-nacos-ribbon-user就写完了,springcloud-nacos-ribbon-order同理,将所有的user修改成order就行了

下面在来新建springcloud-nacos-ribbon-rest
项目结构
在这里插入图片描述
application.properties内容

spring.application.name=springcloud-nacos-ribbon-rest
server.port=18081
spring.cloud.nacos.discovery.server-addr=127.0.0.1:8848

#配置那些服务提供者使用负载均衡
springcloud-nacos-ribbon-user.ribbon.NFLoadBalancerRuleClassName=com.nacos.ribbon.rest.rule.NacosWeightedRule
springcloud-nacos-ribbon-order.ribbon.NFLoadBalancerRuleClassName=com.nacos.ribbon.rest.rule.NacosWeightedRule

启动类,OrderController,UserController,NacosWeightedRule内容如下

@EnableFeignClients(basePackages = {"com.nacos.ribbon.user.feign","com.nacos.ribbon.order.feign"})
@EnableDiscoveryClient
@SpringBootApplication
public class SpringcloudNacosRibbonRestApplication {

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

}

@RequestMapping("order")
@RestController
public class OrderController {
	
	@Autowired
	private OrderFeignClient orderFeignClient;
	
	
	@RequestMapping("findOrderById")
	public String findOrderById(Long orderId) {
		return orderFeignClient.findOrderById(orderId);
		
	}

}

@RequestMapping("user")
@RestController
public class UserController {
	
	@Autowired
	private UserFeignClient userFeignClient;
	
	@GetMapping("findUserByUserId")
	public String findUserByUserId(Long userId) {
		return userFeignClient.findUserByUserId(userId);
		
	}

}


import org.springframework.beans.factory.annotation.Autowired;

import com.alibaba.cloud.nacos.NacosDiscoveryProperties;
import com.alibaba.cloud.nacos.ribbon.NacosServer;
import com.alibaba.nacos.api.naming.pojo.Instance;
import com.netflix.client.config.IClientConfig;
import com.netflix.loadbalancer.AbstractLoadBalancerRule;
import com.netflix.loadbalancer.DynamicServerListLoadBalancer;
import com.netflix.loadbalancer.Server;

public class NacosWeightedRule extends AbstractLoadBalancerRule {

	@Autowired
	private NacosDiscoveryProperties nacosDiscoveryProperties;

	@SuppressWarnings("rawtypes")
	@Override
	public Server choose(Object key) {
		return choose((DynamicServerListLoadBalancer) getLoadBalancer(), key);
	}

	@SuppressWarnings("rawtypes")
	public Server choose(DynamicServerListLoadBalancer lb, Object key) {
		if (lb == null) {
			return null;
		}
		String name = lb.getName();
		System.out.println("[负载均衡权重规则]:" + name);
		try {
			Instance instance = nacosDiscoveryProperties.namingServiceInstance().selectOneHealthyInstance(name);
			System.out.println("[负载均衡权重规则]:" + instance.getInstanceId() + "-----" + instance.getPort() + "-----"
					+ instance.getWeight());
			return new NacosServer(instance);
		} catch (Exception e) {
			System.out.println("[负载均衡权重规则发生异常]:" + e);
		}
		return null;
	}

	@Override
	public void initWithNiwsConfig(IClientConfig clientConfig) {

	}

}

现在项目全部写好了,下面就是运行了
nacos server已经启动好了
然后一次启动以下项目
springcloud-nacos-ribbon-user-provider
第二台user需要修改端口,然后打包,直接使用java -jar 启动即可,方便测试负载均衡
springcloud-nacos-ribbon-user-provider
springcloud-nacos-ribbon-order-provider
springcloud-nacos-ribbon-rest

都启动好之后,我们可以看到nacos控制台有三个服务,其中user服务有两个实例
在这里插入图片描述
点进springcloud-nacos-ribbon-user详情,可以详细的看到有两台服务,这时候我们就可以修改权重了
在这里插入图片描述
然后分别访问
http://localhost:18081/user/findUserByUserId?userId=1
http://localhost:18081/order/findOrderById?orderId=1

当访问/user/findUserByUserId?userId=1的时候,就可以看到两台不同的端口的服务在切换调用

如下图显示,端口为18084与18082的两个实例,权重都是1,那么请求就是均衡的到每一台实例上
在这里插入图片描述

接下来我们修改18082的实例权重为100看看日志情况
在这里插入图片描述
这时候就可以看到,流量基本上都被发到18082的端口实例上了,
在这里插入图片描述
如果做更新的时候,我们就可以将一台服务的权重调成0,然后在下线实例

好了以上就是部署及使用nacos配置权重,使ribbon使用自定义负载均衡手动调节权重了

完整的项目代码也是放在gitee上了,实在需要的话,我会将gitee地址发个各位


版权声明:本文为qq_21082615原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。