# SpringCloud Allibaba
# 入门简介
# why 会出现 SpringCloud alibaba
# Spring Cloud Netflix项目进入维护模式
# Spring Cloud Netflix Projects Entering Maintenance Mode
# 什么是维护模式
将模块置于维护模式,意味着 Spring Cloud 团队将不会再向模块添加新功能。
我们将修复 block 级别的 bug 以及安全问题,我们也会考虑并审查社区的小型 pull request。
# 进入维护模式意味着什么呢?
Spring Cloud Netflix 将不再开发新的组件
我们都知道Spring Cloud 版本迭代算是比较快的,因而出现了很多重大ISSUE都还来不及Fix就又推另一个Release了。进入维护模式意思就是目前一直以后一段时间Spring Cloud Netflix提供的服务和功能就这么多了,不在开发新的组件和功能了。以后将以维护和Merge分支Full Request为主
新组件功能将以其他替代平代替的方式实现
# SpringCloud alibaba带来了什么
# 是什么
诞生:2018.10.31,Spring Cloud Alibaba 正式入驻了 Spring Cloud 官方孵化器,并在 Maven 中央库发布了第一个版本。
# 能干嘛
服务限流降级:默认支持 Servlet、Feign、RestTemplate、Dubbo 和 RocketMQ 限流降级功能的接入,可以在运行时通过控制台实时修改限流降级规则,还支持查看限流降级 Metrics 监控。
服务注册与发现:适配 Spring Cloud 服务注册与发现标准,默认集成了 Ribbon 的支持。
分布式配置管理:支持分布式系统中的外部化配置,配置更改时自动刷新。
消息驱动能力:基于 Spring Cloud Stream 为微服务应用构建消息驱动能力。
阿里云对象存储:阿里云提供的海量、安全、低成本、高可靠的云存储服务。支持在任何应用、任何时间、任何地点存储和访问任意类型的数据。
分布式任务调度:提供秒级、精准、高可靠、高可用的定时(基于 Cron 表达式)任务调度服务。同时提供分布式的任务执行模型,如网格任务。网格任务支持海量子任务均匀分配到所有 Worker(schedulerx-client)上执行。
# 下载地址
# 怎么玩
# SpringCloud alibaba学习资料获取
官网
英文
spring 官网文档 (opens new window)
中文
# SpringCloud Alibaba Nacos服务注册和配置中心
# Nacos简介
# Nacos 是什么
一个更易于构建云原生应用的动态服务发现、配置管理和服务管理平台。
Nacos: Dynamic Naming and Configuration Service
Nacos就是注册中心 + 配置中心的组合
Nacos = Eureka+Config +Bus
# 能干嘛
- 替代Eureka做服务注册中心
- 替代Config做服务配置中心
# 去哪下
# 各种注册中心比较
据说 Nacos 在阿里巴巴内部有超过 10 万的实例运行,已经过了类似双十一等各种大型流量的考验
# 安装并运行Nacos
ps : 本地Java8+Maven环境已经OK
下载地址
解压运行
用 nodepad++ 打开 bin 目录下的 startup.cmd, 将 MODE
修改为 standalone
set MODE="standalone"
双击启动
命令运行成功后直接访问
账号密码 都是 nacos
# Nacos作为服务注册中心演示
# 官网文档
# 基于Nacos的服务提供者
# 建 module
module 名 : cloudalibaba-provider-payment9001
# 改 POM
父 POM
<!-- spring cloud alibaba 2.2.7.RELEASE -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
<version>2.2.7.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
2
3
4
5
6
7
8
模块 POM
<?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">
<parent>
<artifactId>springcloud-learn</artifactId>
<groupId>com.yixihan.springcloud</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>cloudalibaba-provider-payment9002</artifactId>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
</properties>
<dependencies>
<!--SpringCloud ailibaba nacos -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<!-- SpringBoot整合Web组件 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<!--日常通用jar包配置-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
</project>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
# 写 YAML
server:
port: 9001
spring:
application:
name: nacos-payment-provider
cloud:
nacos:
discovery:
server-addr: localhost:8848 #配置Nacos地址
management:
endpoints:
web:
exposure:
include: '*'
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# 主启动
package com.yixihan.springcloud;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
/**
* @author : yixihan
* @create : 2022-01-24-11:21
*/
@SpringBootApplication
@EnableDiscoveryClient
public class PaymentMain9001 {
public static void main(String[] args) {
SpringApplication.run (PaymentMain9001.class, args);
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# 业务类
package com.yixihan.springcloud.controller;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
/**
* @author : yixihan
* @create : 2022-01-24-11:22
*/
@RestController
public class PaymentController {
@Value ("${server.port}")
private String serverPort;
@GetMapping(value = "/payment/nacos/{id}")
public String getPayment(@PathVariable("id") Integer id)
{
return "nacos registry, serverPort: "+ serverPort+"\t id"+id;
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# 测试
nacos 控制台
接口
# 参照 9001 构建 9002
新建cloudalibaba-provider-payment9002
其余省略
或者取巧不想新建重复体力劳动,直接拷贝虚拟端口映射
# 基于Nacos的服务消费者
# 建 module
module 名 : cloudalibaba-consumer-nacos-order83
# 改 POM
<?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">
<parent>
<artifactId>springcloud-learn</artifactId>
<groupId>com.yixihan.springcloud</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>cloudalibaba-consumer-nacos-order83</artifactId>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
</properties>
<dependencies>
<!--SpringCloud ailibaba nacos -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<!-- 引入自己定义的api通用包,可以使用Payment支付Entity -->
<dependency>
<groupId>com.yixihan.springcloud</groupId>
<artifactId>cloud-api-commons</artifactId>
<version>${project.version}</version>
</dependency>
<!-- SpringBoot整合Web组件 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<!--日常通用jar包配置-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
</project>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
为什么nacos支持负载均衡
# 写 YAML
server:
port: 83
spring:
application:
name: nacos-order-consumer
cloud:
nacos:
discovery:
server-addr: localhost:8848
#消费者将要去访问的微服务名称(注册成功进nacos的微服务提供者)
service-url:
nacos-user-service: http://nacos-payment-provider
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# 主启动
package com.yixihan.springcloud;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
/**
* @author : yixihan
* @create : 2022-01-24-12:47
*/
@SpringBootApplication
@EnableDiscoveryClient
public class OrderNacosMain83 {
public static void main(String[] args) {
SpringApplication.run (OrderNacosMain83.class, args);
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# 业务类
config
package com.yixihan.springcloud.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;
/**
* @author : yixihan
* @create : 2022-01-24-12:47
*/
@Configuration
public class ApplicationContextBean {
@Bean
@LoadBalanced
public RestTemplate getRestTemplate () {
return new RestTemplate ();
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
controller
package com.yixihan.springcloud.controller;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
import javax.annotation.Resource;
/**
* @author : yixihan
* @create : 2022-01-24-12:48
*/
@RestController
@Slf4j
public class OrderNacosController {
@Resource
private RestTemplate restTemplate;
@Value("${service-url.nacos-user-service}")
private String serverURL;
@GetMapping("/consumer/payment/nacos/{id}")
public String paymentInfo(@PathVariable("id") Long id) {
return restTemplate.getForObject(serverURL+"/payment/nacos/"+id,String.class);
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
# 测试
nacos 控制台
测试接口
# 服务注册中心对比
# nacos 全景图
# nacos 和 CAP
# Nacos 切换
Nacos 支持AP和CP模式的切换
C是所有节点在同一时间看到的数据是一致的;而A的定义是所有的请求都会收到响应。
何时选择使用何种模式?
一般来说,如果不需要存储服务级别的信息且服务实例是通过nacos-client注册,并能够保持心跳上报,那么就可以选择AP模式。当前主流的服务如 Spring cloud 和 Dubbo 服务,都适用于AP模式,AP模式为了服务的可能性而减弱了一致性,因此AP模式下只支持注册临时实例。
如果需要在服务级别编辑或者存储配置信息,那么 CP 是必须,K8S服务和DNS服务则适用于CP模式。
CP模式下则支持注册持久化实例,此时则是以 Raft 协议为集群运行模式,该模式下注册实例之前必须先注册服务,如果服务不存在,则会返回错误。
切换命令
curl -X PUT '$NACOS_SERVER:8848/nacos/v1/ns/operator/switches?entry=serverMode&value=CP'
# Nacos作为服务配置中心演示
# Nacos作为配置中心-基础配置
# 建 module
module 名 : cloudalibaba-config-nacos-client3377
# 改 POM
# 写 YAML
bootstrap
# nacos配置
server:
port: 3377
spring:
application:
name: nacos-config-client
cloud:
nacos:
discovery:
server-addr: localhost:8848 #Nacos服务注册中心地址
config:
server-addr: localhost:8848 #Nacos作为配置中心地址
file-extension: yaml #指定yaml格式的配置
# ${spring.application.name}-${spring.profile.active}.${spring.cloud.nacos.config.file-extension}
# nacos-config-client-dev.yaml
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
application
spring:
profiles:
active: dev # 表示开发环境
2
3
4
why配置两个
Nacos同springcloud-config一样,在项目初始化时,要保证先从配置中心进行配置拉取,拉取配置之后,才能保证项目的正常启动。
springboot中配置文件的加载是存在优先级顺序的,bootstrap优先级高于application
# 主启动
package com.yixihan.springcloud;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
/**
* @author : yixihan
* @create : 2022-01-24-13:06
*/
@SpringBootApplication
@EnableDiscoveryClient
public class NacosConfigClientMain3377 {
public static void main(String[] args) {
SpringApplication.run (NacosConfigClientMain3377.class, args);
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# 业务类
package com.yixihan.springcloud.controller;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* @author : yixihan
* @create : 2022-01-24-13:07
*/
@RestController
@Slf4j
@RefreshScope //在控制器类加入@RefreshScope注解使当前类下的配置支持Nacos的动态刷新功能。
public class ConfigClientController {
@Value("${config.info}")
private String configInfo;
@GetMapping("/config/info")
public String getConfigInfo() {
return configInfo;
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
@RefreshScope
# 在Nacos中添加配置信息
Nacos中的匹配规则
最后公式:
${spring.application.name}-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension}
spring.application.name 为微服务名, 默认为prefix
spring.profile.active 即为当前环境对应的 profile,可以通过配置项 spring.profile.active 来配置。
file-exetension 为配置内容的数据格式,可以通过配置项 spring.cloud.nacos.config.file-extension 来配置
2
3
4
5
小总结
实操
新增配置
Data ID 为最后推出来的文件名
历史配置
Nacos会记录配置文件的历史版本默认保留30天,此外还有一键回滚功能,回滚操作将会触发配置更新
回滚
# 测试
ps : nacos 自带动态刷新
# Nacos作为配置中心-分类配置
# 问题 - 多环境多项目管理
问题1:
实际开发中,通常一个系统会准备
dev开发环境
test测试环境
prod生产环境。
如何保证指定环境启动时服务能正确读取到Nacos上相应环境的配置文件呢?
问题 2 :
一个大型分布式微服务系统会有很多微服务子项目,每个微服务项目又都会有相应的开发环境、测试环境、预发环境、正式环境......
那怎么对这些微服务配置进行管理呢?
# Nacos的图形化管理界面
配置管理
命名空间
# Namespace+Group+Data ID三者关系?为什么这么设计?
是什么
类似Java里面的package名和类名
最外层的namespace是可以用于区分部署环境的,Group和DataID逻辑上区分两个目标对象。
三者情况
默认情况
Namespace=public,Group=DEFAULT_GROUP, 默认Cluster是DEFAULT
Nacos默认的命名空间是public,Namespace主要用来实现隔离。
比方说我们现在有三个环境:开发、测试、生产环境,我们就可以创建三个Namespace,不同的Namespace之间是隔离的。
Group默认是DEFAULT_GROUP,Group可以把不同的微服务划分到同一个分组里面去
Service就是微服务;一个Service可以包含多个Cluster(集群),Nacos默认Cluster是DEFAULT,Cluster是对指定微服务的一个虚拟划分。
比方说为了容灾,将Service微服务分别部署在了杭州机房和广州机房,这时就可以给杭州机房的Service微服务起一个集群名称(HZ),给广州机房的Service微服务起一个集群名称(GZ),还可以尽量让同一个机房的微服务互相调用,以提升性能。
最后是Instance,就是微服务的实例。
# DataID方案
指定spring.profile.active和配置文件的DataID来使不同环境下读取不同的配置
默认空间+默认分组+新建dev和test两个DataID
新建dev配置DataID
新建test配置DataID
通过spring.profile.active属性就能进行多环境下配置文件的读取
测试
active = test
active = dev
# Group方案
通过Group实现环境区分
新建 Group
配置如图
bootstrap+application
application
bootstrap
测试
group = TEST_GROUP
group = DEV_GROUP
# Namespace方案
新建dev/test的Namespace
回到服务管理-服务列表查看
按照域名配置填写
bootstarp 和 application
bootstrap
# nacos配置
server:
port: 3377
spring:
application:
name: nacos-config-client
cloud:
nacos:
discovery:
server-addr: localhost:8848 #Nacos服务注册中心地址
config:
server-addr: localhost:8848 #Nacos作为配置中心地址
file-extension: yaml #指定yaml格式的配置
group: DEV_GROUP
namespace: f1201f94-dace-4d11-987b-41d53d01e2d6
# ${spring.application.name}-${spring.profile.active}.${spring.cloud.nacos.config.file-extension}
# nacos-config-client-dev.yaml
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
application
spring:
profiles:
# active: test # 表示测试环境
active: dev # 表示开发环境
# active: info # 表示开发环境
2
3
4
5
6
测试
# Nacos集群和持久化配置(重要)
# 官网说明
官网架构图
真实情况
# 说明
默认Nacos使用嵌入式数据库实现数据的存储。所以,如果启动多个默认配置下的Nacos节点,数据存储是存在一致性问题的。
为了解决这个问题,Nacos采用了集中式存储的方式来支持集群化部署,目前只支持MySQL的存储。
按照上述,我们需要mysql数据库
官网说明
# Nacos持久化配置解释
# Nacos默认自带的是嵌入式数据库derby
# derby到mysql切换配置步骤
在
nacos\conf
目录下找到sql脚本
在nacos\conf目录下找到application.properties
最后添加内容
spring.datasource.platform=mysql
db.num=1
db.url.0=jdbc:mysql://localhost:3306/nacos_config?characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true&serverTimezone=UTC
db.user=root
db.password=123456
2
3
4
5
6
7
重新启动并访问 nacos
新建配置文件
mysql 数据库查看
# Linux版Nacos+MySQL生产环境配置
预计需要,1个Nginx+3个nacos注册中心+1个mysql
# Nacos下载Linux版
下载后解压安装至 /opt/nacos/nacos1
# 集群配置步骤(重点)
# Linux服务器上mysql数据库配置
使用 Navicat 连接云服务器 mysql, 建立 nacos_config
数据库
使用 /opt/nacos/nacos1/conf
目录下的 nacos-mysql.sql 文件建表
# application.properties 配置
在 /opt/nacos/nacos1/conf
下操作
application.properties 自带备份文件 application.properties.example, 不需要额外备份
cd /opt/nacos/nacos1/conf
# 编辑 application.properties
vim application.properties
# 修改内容如下
#*************** Config Module Related Configurations ***************#
### If use MySQL as datasource:
spring.datasource.platform=mysql
### Count of DB:
db.num=1
### Connect URL of DB:
db.url.0=jdbc:mysql://127.0.0.1:1617/nacos_config?characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true&useUnicode=true&useSSL=false&serverTimezone=UTC
db.user.0=username
db.password.0=password
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# Linux服务器上nacos的集群配置cluster.conf
在 /opt/nacos/nacos1/conf
下操作
cd /opt/nacos/nacos1/conf
# 备份cluster.conf 文件
cp cluster.conf.example cluster.conf
# 查看内网 IP
hostname -I
# 编辑 cluster.conf
vim cluster.conf
# 添加内容如下
# 内网IP : 端口号
10.0.4.12:3333
10.0.4.12:4444
10.0.4.12:5555
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 编辑Nacos的启动脚本startup.sh,使它能够接受不同的启动端口
在 /opt/nacos/nacos1/bin
下操作
cd /opt/nacos/nacos1/bin
# 备份 startup.sh
cp startup.sh startup.sh.example
# 修改内容之一, 增加端口选择 -y
while getopts ":m:f:s:c:p:y:" opt
do
case $opt in
m)
MODE=$OPTARG;;
f)
FUNCTION_MODE=$OPTARG;;
s)
SERVER=$OPTARG;;
c)
MEMBER_LIST=$OPTARG;;
p)
EMBEDDED_STORAGE=$OPTARG;;
y)
PORT=$OPTARG;;
?)
echo "Unknown parameter"
exit 1;;
esac
done
# 修改内容之二 修改jvm 可选
# 修改 内存大小, 根据自己机器性能选择性修改
# 修改内容之三
# start
echo "$JAVA $JAVA_OPT_EXT_FIX ${JAVA_OPT}" > ${BASE_DIR}/logs/start.out 2>&1 &
if [[ "$JAVA_OPT_EXT_FIX" == "" ]]; then
nohup "$JAVA" -Dserver.port=${PORT} ${JAVA_OPT} nacos.nacos >> ${BASE_DIR}/logs/start.out 2>&1 &
else
nohup "$JAVA" -Dserver.port=${PORT} "$JAVA_OPT_EXT_FIX" ${JAVA_OPT} nacos.nacos >> ${BASE_DIR}/logs/start.out 2>&1 &
fi
echo "nacos is starting,you can check the ${BASE_DIR}/logs/start.out"
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
修改内容之一
修改内容之二
修改内容之三
# 全部配置
#!/bin/bash
# Copyright 1999-2018 Alibaba Group Holding Ltd.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
cygwin=false
darwin=false
os400=false
case "`uname`" in
CYGWIN*) cygwin=true;;
Darwin*) darwin=true;;
OS400*) os400=true;;
esac
error_exit ()
{
echo "ERROR: $1 !!"
exit 1
}
[ ! -e "$JAVA_HOME/bin/java" ] && JAVA_HOME=$HOME/jdk/java
[ ! -e "$JAVA_HOME/bin/java" ] && JAVA_HOME=/usr/java
[ ! -e "$JAVA_HOME/bin/java" ] && JAVA_HOME=/opt/taobao/java
[ ! -e "$JAVA_HOME/bin/java" ] && unset JAVA_HOME
if [ -z "$JAVA_HOME" ]; then
if $darwin; then
if [ -x '/usr/libexec/java_home' ] ; then
export JAVA_HOME=`/usr/libexec/java_home`
elif [ -d "/System/Library/Frameworks/JavaVM.framework/Versions/CurrentJDK/Home" ]; then
export JAVA_HOME="/System/Library/Frameworks/JavaVM.framework/Versions/CurrentJDK/Home"
fi
else
JAVA_PATH=`dirname $(readlink -f $(which javac))`
if [ "x$JAVA_PATH" != "x" ]; then
export JAVA_HOME=`dirname $JAVA_PATH 2>/dev/null`
fi
fi
if [ -z "$JAVA_HOME" ]; then
error_exit "Please set the JAVA_HOME variable in your environment, We need java(x64)! jdk8 or later is better!"
fi
fi
export SERVER="nacos-server"
export MODE="cluster"
export FUNCTION_MODE="all"
export MEMBER_LIST=""
export EMBEDDED_STORAGE=""
while getopts ":m:f:s:c:p:y:" opt
do
case $opt in
m)
MODE=$OPTARG;;
f)
FUNCTION_MODE=$OPTARG;;
s)
SERVER=$OPTARG;;
c)
MEMBER_LIST=$OPTARG;;
p)
EMBEDDED_STORAGE=$OPTARG;;
y)
PORT=$OPTARG;;
?)
echo "Unknown parameter"
exit 1;;
esac
done
export JAVA_HOME
export JAVA="$JAVA_HOME/bin/java"
export BASE_DIR=`cd $(dirname $0)/..; pwd`
export CUSTOM_SEARCH_LOCATIONS=file:${BASE_DIR}/conf/
#===========================================================================================
# JVM Configuration
#===========================================================================================
if [[ "${MODE}" == "standalone" ]]; then
JAVA_OPT="${JAVA_OPT} -Xms512m -Xmx512m -Xmn256m"
JAVA_OPT="${JAVA_OPT} -Dnacos.standalone=true"
else
if [[ "${EMBEDDED_STORAGE}" == "embedded" ]]; then
JAVA_OPT="${JAVA_OPT} -DembeddedStorage=true"
fi
JAVA_OPT="${JAVA_OPT} -server -Xms512m -Xmx512m -Xmn512m -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=320m"
JAVA_OPT="${JAVA_OPT} -XX:-OmitStackTraceInFastThrow -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=${BASE_DIR}/logs/java_heapdump.hprof"
JAVA_OPT="${JAVA_OPT} -XX:-UseLargePages"
fi
if [[ "${FUNCTION_MODE}" == "config" ]]; then
JAVA_OPT="${JAVA_OPT} -Dnacos.functionMode=config"
elif [[ "${FUNCTION_MODE}" == "naming" ]]; then
JAVA_OPT="${JAVA_OPT} -Dnacos.functionMode=naming"
fi
JAVA_OPT="${JAVA_OPT} -Dnacos.member.list=${MEMBER_LIST}"
JAVA_MAJOR_VERSION=$($JAVA -version 2>&1 | sed -E -n 's/.* version "([0-9]*).*$/\1/p')
if [[ "$JAVA_MAJOR_VERSION" -ge "9" ]] ; then
JAVA_OPT="${JAVA_OPT} -Xlog:gc*:file=${BASE_DIR}/logs/nacos_gc.log:time,tags:filecount=10,filesize=102400"
else
JAVA_OPT_EXT_FIX="-Djava.ext.dirs=${JAVA_HOME}/jre/lib/ext:${JAVA_HOME}/lib/ext"
JAVA_OPT="${JAVA_OPT} -Xloggc:${BASE_DIR}/logs/nacos_gc.log -verbose:gc -XX:+PrintGCDetails -XX:+PrintGCDateStamps -XX:+PrintGCTimeStamps -XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=10 -XX:GCLogFileSize=100M"
fi
JAVA_OPT="${JAVA_OPT} -Dloader.path=${BASE_DIR}/plugins/health,${BASE_DIR}/plugins/cmdb,${BASE_DIR}/plugins/selector"
JAVA_OPT="${JAVA_OPT} -Dnacos.home=${BASE_DIR}"
JAVA_OPT="${JAVA_OPT} -jar ${BASE_DIR}/target/${SERVER}.jar"
JAVA_OPT="${JAVA_OPT} ${JAVA_OPT_EXT}"
JAVA_OPT="${JAVA_OPT} --spring.config.additional-location=${CUSTOM_SEARCH_LOCATIONS}"
JAVA_OPT="${JAVA_OPT} --logging.config=${BASE_DIR}/conf/nacos-logback.xml"
JAVA_OPT="${JAVA_OPT} --server.max-http-header-size=524288"
if [ ! -d "${BASE_DIR}/logs" ]; then
mkdir ${BASE_DIR}/logs
fi
echo "$JAVA $JAVA_OPT_EXT_FIX ${JAVA_OPT}"
if [[ "${MODE}" == "standalone" ]]; then
echo "nacos is starting with standalone"
else
echo "nacos is starting with cluster"
fi
# check the start.out log output file
if [ ! -f "${BASE_DIR}/logs/start.out" ]; then
touch "${BASE_DIR}/logs/start.out"
fi
# start
echo "$JAVA $JAVA_OPT_EXT_FIX ${JAVA_OPT}" > ${BASE_DIR}/logs/start.out 2>&1 &
if [[ "$JAVA_OPT_EXT_FIX" == "" ]]; then
nohup "$JAVA" -Dserver.port=${PORT} ${JAVA_OPT} nacos.nacos >> ${BASE_DIR}/logs/start.out 2>&1 &
else
nohup "$JAVA" -Dserver.port=${PORT} "$JAVA_OPT_EXT_FIX" ${JAVA_OPT} nacos.nacos >> ${BASE_DIR}/logs/start.out 2>&1 &
fi
echo "nacos is starting,you can check the ${BASE_DIR}/logs/start.out"
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
# 复制三份 nacos 文件
cd /opt/nacos
cp -r nacos1 nacos2
cp -r nacos2 nacos3
2
3
# Nginx的配置,由它作为负载均衡器
查看 nginx 是否有 stream 模块
cd /usr/local/nginx/sbin
./nginx -V
2
若没有 stream 模块则需要安装
# nginx 需要安装 stream 模块
备份原来的 nginx 目录
cd /usr/local/
cp -r nginx/ nginx-noStream/
2
转到 nginx 安装目录 /opt/nginx-1.20.1/
cd /opt/nginx-1.20.1/
# 下载 stream 模块
./configure --prefix=/usr/local/nginx --with-http_stub_status_module --with-http_ssl_module --with-stream
# 安装
make && make install
# 查看是否安装完成
cd /usr/local/nginx/sbin
./nginx -V
2
3
4
5
6
7
8
9
10
11
# 修改nginx的配置文件
在 /usr/local/nginx/conf
目录下操作
cd /usr/local/nginx/conf
vim nginx.conf
# http 均衡负载 写在 http 模块最后面
upstream nacos-server {
server 10.0.4.12:3333;
server 10.0.4.12:4444;
server 10.0.4.12:5555;
}
server {
listen 8848;
location / {
proxy_pass http://nacos-server/;
}
# tcp 转发 写在 http 模块外面
stream {
upstream NACOS_ADDR_9848 {
server 10.0.4.12:4333;
server 10.0.4.12:5444;
server 10.0.4.12:6555;
}
server {
listen 9848 so_keepalive=on;
proxy_connect_timeout 3s;
proxy_pass NACOS_ADDR_9848;
tcp_nodelay on;
proxy_buffer_size 32k;
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
# 完整配置
#user nobody;
worker_processes 1;
#error_log logs/error.log;
#error_log logs/error.log notice;
#error_log logs/error.log info;
#pid logs/nginx.pid;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
#log_format main '$remote_addr - $remote_user [$time_local] "$request" '
# '$status $body_bytes_sent "$http_referer" '
# '"$http_user_agent" "$http_x_forwarded_for"';
#access_log logs/access.log main;
sendfile on;
#tcp_nopush on;
#keepalive_timeout 0;
keepalive_timeout 65;
#gzip on;
#upstream NACOS {
# server 127.0.0.1:3333 max_fails=3 fail_timeout=5s;
# server 127.0.0.1:4444 max_fails=3 fail_timeout=5s;
# server 127.0.0.1:5555 max_fails=3 fail_timeout=5s;
#}
server {
listen 80;
server_name localhost;
#charset koi8-r;
#access_log logs/host.access.log main;
location / {
root html;
index index.html index.htm;
#proxy_pass http://NACOS;
#proxy_connect_timeout 75;
#proxy_read_timeout 400;
#proxy_send_timeout 400;
#client_max_body_size 100m;
#proxy_set_header Host $host;
#proxy_set_header X-Real-IP $remote_addr;
#proxy_set_header X-Forwarded-For $remote_addr;
}
#error_page 404 /404.html;
# redirect server error pages to the static page /50x.html
#
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
# proxy the PHP scripts to Apache listening on 127.0.0.1:80
#
#location ~ \.php$ {
# proxy_pass http://127.0.0.1;
#}
# pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
#
#location ~ \.php$ {
# root html;
# fastcgi_pass 127.0.0.1:9000;
# fastcgi_index index.php;
# fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name;
# include fastcgi_params;
#}
# deny access to .htaccess files, if Apache's document root
# concurs with nginx's one
#
#location ~ /\.ht {
# deny all;
#}
}
# another virtual host using mix of IP-, name-, and port-based configuration
#
#server {
# listen 8000;
# listen somename:8080;
# server_name somename alias another.alias;
# location / {
# root html;
# index index.html index.htm;
# }
#}
# HTTPS server
#
#server {
# listen 443 ssl;
# server_name localhost;
# ssl_certificate cert.pem;
# ssl_certificate_key cert.key;
# ssl_session_cache shared:SSL:1m;
# ssl_session_timeout 5m;
# ssl_ciphers HIGH:!aNULL:!MD5;
# ssl_prefer_server_ciphers on;
# location / {
# root html;
# index index.html index.htm;
# }
#}
upstream nacos-server {
server 10.0.4.12:3333;
server 10.0.4.12:4444;
server 10.0.4.12:5555;
}
server {
listen 8848;
location / {
proxy_pass http://nacos-server/;
}
}
}
stream {
upstream NACOS_ADDR_9848 {
server 10.0.4.12:4333;
server 10.0.4.12:5444;
server 10.0.4.12:6555;
}
server {
listen 9848 so_keepalive=on;
proxy_connect_timeout 3s;
proxy_pass NACOS_ADDR_9848;
tcp_nodelay on;
proxy_buffer_size 32k;
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
# 启动 nacos 集群
# 启动 MySQL
systemctl start mysqld.service
# 启动 nacos
cd /opt/nacos
./nacos1/bin/startup.sh -y 3333
./nacos2/bin/startup.sh -y 4444
./nacos3/bin/startup.sh -y 5555
# 启动 nginx
cd /usr/local/nginx/sbin
./nginx
2
3
4
5
6
7
8
9
10
11
12
13
# 测试
访问 nacos 控制台
新建一个配置测试
将微服务注册进 nacos 集群
yaml 配置 - 客户端
spring:
cloud:
nacos:
discovery:
server-addr: 175.24.229.41:8848
2
3
4
5
yaml 配置 - 配置端
spring:
cloud:
nacos:
discovery:
server-addr: 175.24.229.41:8848 #Nacos服务注册中心地址
config:
server-addr: 175.24.229.41:8848 #Nacos作为配置中心地址
file-extension: yaml #指定yaml格式的配置
2
3
4
5
6
7
8