Nacos

下载

安装包:https://github.com/alibaba/nacos/releases
下载nacos-server-$version.zip包,Windows下载解压后(.zip),直接点击bin/startup.cmd就可以了。

默认启动端口是8848,可以在conf下找到application.properties文件,对server.port进行修改。

可视化控制台:http://localhost:8848/nacos, 默认的用户名和密码都是nacos。
在这里插入图片描述
在这里插入图片描述

nacos.zip解压,绿色版,启动服务。注意:解压路径一定不要有中文或括号之类的字符,包括(x86),否则可能无法启动。

  • 当无法启动(一闪而过)时:可以使用cmd进入nacos的bin文件夹,执行startup.cmd,出错就会打印错误信息,拿到错误信息就可以百度搜索解决办法了。
  • nacos版本尽量使用Spring Cloud Alibaba里面的nacos版本。
  • nacos执行startup.cmd,默认以cluster集群方式启动,此时需要mysql建库来支撑数据的持久化,建库脚本在D:\Program Files\nacos\conf\nacos-mysql.sql;不配数据库直接启动第一个会报db.num is null错误
  • 以单机模式启动,进入cmd黑窗口,执行startup.cmd -m standalone,内置了一个嵌入式数据库derby,单机也可以存储数据

遇到的问题

双击startup.cmd无法启动

因为解压到了D:\Program Files (x86)下,解压路径不能包含括号,移到D:\Program Files下完美解决。

启动报db.num is null错误

在这里插入图片描述
nacos执行startup.cmd,默认以cluster集群方式启动,此时需要mysql建库来支撑数据的持久化,建库脚本在D:\Program Files\nacos\conf\nacos-mysql.sql;不配数据库直接启动第一个会报db.num is null错误

解决方案:

  • 建库
  • 单机启动

单机模式启动

执行startup.cmd -m standalone
在这里插入图片描述
如果不喜欢以命令的方式启动,可以通过修改D:\Program Files\nacos\bin\startup.cmd文件,
然后我们将原来的set MODE="cluster"集群改为set MODE="standalone"单机
,然后在直接鼠标点击startup.cmd启动即可。
在这里插入图片描述

1. 服务注册

在父工程路径下创建子工程,让子工程继承父工程的环境依赖,子工程pom.xml 中添加 nacos 发现组件(可以放在父pom,当项目庞大起来,子工程越来越多,此时继承父pom即可,避免重复代码)。

子项目(提供者)

pom.xml配置

<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>

application.yml 中配置,项目启动时是否会注册,取决于spring.application.name的配置
或者不使用application.yml ,直接在主类上使用@EnableDiscoveryClient。

server:
  port: 8081

spring:
  cloud:
    nacos:
      discovery:
        # 指定nacos server地址,不用写http://,不配置默认是本机localhost:8848
        server-addr: localhost:8848
  application:
  	# 指定提供者的名字,注册服务的关键因素,注释掉name就不会再注册
    name: my-provider

项目启动就会自动在注册中心注册一个实例,如图所示:
在这里插入图片描述

在这里插入图片描述

小提示:idea可以启动同一个项目多次,在run 配置中勾选Allow parallel run即可启动多个实例,记得修改端口再启动哦。

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

2. 服务发现

子项目(消费者)
第一步:添加依赖;
第二步:使用DiscoveryClient来获取提供者列表;
第三步:使用RestTemplate进行服务调用,但是RestTemplate没有被纳入Spring管理,无法直接使用注解,可以自己实现一个配置类,将RestTemplate纳入Spring管理,

2.1 添加依赖

pom.xml 添加 discovery,完成服务发现。

<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>

2.2 通过RestTemplate 进行服务调用

DiscoveryClient是专门负责服务注册和发现的,我们可以通过它获取到注册到注册中心的所有服务
RestTemplate是专门进行服务调用的

2.2.1 RestTemplate 纳入Spring容器管理

添加一个配置类,使用@Bean将RestTemplate纳入Spring容器管理,业务层就可用@Autowired直接依赖使用。

package com.gs.consumer.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;

@Configuration
public class ConsumerConfig {

	@Bean
	public RestTemplate restTemplate(){
		return new RestTemplate();
	}
}

2.2.2 服务调用

通过 discoveryClient 发现注册到 nacos 中的 provider 服务,再通过RestTemplate 进行服务调用。
整合:这种方式比较麻烦,而且随机数的生成也不合理,稍后介绍更便捷用法-Ribbon。

package com.gs.consumer.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

import java.util.List;
import java.util.concurrent.ThreadLocalRandom;

@RestController
public class ConsumerController {
	@Autowired
	private RestTemplate restTemplate; // 前提:RestTemplate 纳入Spring容器管理
	@Autowired
	private DiscoveryClient discoveryClient;

	@GetMapping("/instances")
	public List<ServiceInstance> instances(){
		List<ServiceInstance> provider = discoveryClient.getInstances("my-provider");
		return provider;
	}

	@GetMapping("/consumer")
	public String test1() {
		// 获取提供者实例
		List<ServiceInstance> provider = discoveryClient.getInstances("my-provider");
		// 根据提供者个数生成随机数,随机调用提供者
		// 整合:这种方式比较麻烦,而且随机数的生成也不合理,稍后介绍更便捷用法-Ribbon。
		int index = ThreadLocalRandom.current().nextInt(provider.size());
		// 调用提供者实例的index方法
		String url = provider.get(index).getUri() + "/index";
		return "consumer随机远程调用provier:" + this.restTemplate.getForObject(url, String.class);
	}
}

在这里插入图片描述
在这里插入图片描述

3. Ribbon 负载均衡

3.1 优化RestTemplate

使用Ribbon优化上述的DiscoveryClient 和 RestTemplate 用法。
在配置类上使用@Bean + @LoadBalanced注解,将RestTemplate纳入Spring容器管理。
注意:使用Ribbon负载均衡的时候服务名中不能使用下划线,不然会找不到服务。

package com.gs.consumer.config;

import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;

@Configuration
public class ConsumerConfig {
	@Bean
	@LoadBalanced
	public RestTemplate restTemplate(){
		return new RestTemplate();
	}
}

在调用时不需要再使用DiscoveryClient进行服务列表的获取,不需要自行生成随机数来进行负载分发,将一切交给Ribbon。
我们只需要提供url,形如http://serviceId/api

@RestController
public class ConsumerController {
    @Autowired
    private RestTemplate restTemplate;

    @GetMapping("/consumer")
    public String index(){
        return "consumer随机远程调用provier:" + this.restTemplate.getForObject("http://my-provider/index", String.class);
    }

}

负载均衡,默认策略是随机,权重1:1
测试:
小提示:idea可以启动同一个项目多次,在run 配置中勾选Allow parallel run即可启动多个实例,记得修改端口再启动哦。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

3.2 负载均衡策略

随机(默认)

server:
  port: 8081
my-provider:
  ribbon:
    NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule

3.2.1 自定义策略(未实现待测试)

  1. 自定义策略类BalanceWeightRule
  2. 修改nacos默认的随机策略,@Configuration使用getRule方法,返回自定义的IRule
  3. 配置指定要使用的策略类全限定名
3.2.1.1 自定义策略类BalanceWeightRule

自定义策略,继承AbstractLoadBalancerRule,重写choose方法
在这里插入图片描述

package com.gs.provider.config;

import com.alibaba.cloud.nacos.NacosDiscoveryProperties;
import com.alibaba.cloud.nacos.ribbon.NacosServer;
import com.alibaba.nacos.api.exception.NacosException;
import com.alibaba.nacos.api.naming.NamingService;
import com.alibaba.nacos.api.naming.pojo.Instance;
import com.netflix.client.config.IClientConfig;
import com.netflix.loadbalancer.AbstractLoadBalancerRule;
import com.netflix.loadbalancer.BaseLoadBalancer;
import com.netflix.loadbalancer.Server;
import org.springframework.beans.factory.annotation.Autowired;

/**
 * Nacos 自定义负载策略
 */
public class BalanceWeightRule extends AbstractLoadBalancerRule {
	@Autowired
	private NacosDiscoveryProperties discoveryProperties;

	@Override
	public Server choose(Object o) {
		// 获取负载均衡的对象
		BaseLoadBalancer baseLoadBalancer = (BaseLoadBalancer) getLoadBalancer();

		// 获取当前调用的微服务的名称
		String serviceName = baseLoadBalancer.getName();

		// 获取Nocas服务发现的相关组件API
		NamingService namingService = discoveryProperties.namingServiceInstance();

		try {
			// 获取一个基于 nacos client 实现权重的负载均衡算法
			Instance instance = namingService.selectOneHealthyInstance(serviceName);
			System.out.println("选择的实例是port={" + instance.getPort() + "},instance={" + instance + "}");

			// 返回一个nacos的server
			return new NacosServer(instance);
		} catch (NacosException e) {
			e.printStackTrace();
			return null;
		}
	}

	@Override
	public void initWithNiwsConfig(IClientConfig iClientConfig) {

	}
}

3.2.1.2 替换掉nacos默认的随机策略
package com.gs.provider.config;

import com.netflix.loadbalancer.IRule;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class RibbonConfig {

	@Bean
	public IRule getRule() {
		// 实现带有权重的负载均衡策略
		return new BalanceWeightRule();
	}
}

3.2.1.3 配置指定策略
server:
  port: 8082

spring:
  application:
    # 注册服务的关键因素,注释掉name就不会再注册
    name: my-provider

# 针对此服务设置负载策略
my-provider:
  ribbon:
    NFLoadBalancerRuleClassName: com.gs.provider.config.BalanceWeightRule

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值