谷粒商城学习笔记(一)
后续笔记正在整理中,相关代码也会一同上传至gitee,敬请关注。
如果笔记中有误或有更好的解决方案,可以在评论区留言,我会及时回复更新。
目录
1. 项目简介
简介可以去视频里了解,这里就不再赘述了,直接步入正题。
https://www.bilibili.com/video/BV1np4y1C7Yf?p=1
2. 环境搭建
需要一台linux,这里我使用阿里云的服务器,centos8.0 64位,2核4G
配置docker环境
https://docs.docker.com/engine/install/centos/
#卸载系统之前的docker
sudo yum remove docker \
docker-client \
docker-client-latest \
docker-common \
docker-latest \
docker-latest-logrotate \
docker-logrotate \
docker-engine
sudo yum install -y yum-utils
# 配置镜像
sudo yum-config-manager \
--add-repo \
https://download.docker.com/linux/centos/docker-ce.repo
sudo yum install docker-ce docker-ce-cli containerd.io
sudo systemctl start docker
# 设置开机自启动
sudo systemctl enable docker
docker -v
sudo docker images
配置镜像加速
sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<-'EOF'
{
"registry-mirrors": ["https://chqac97z.mirror.aliyuncs.com"]
}
EOF
sudo systemctl daemon-reload
sudo systemctl restart docker
安装Mysql
sudo docker pull mysql:5.7
# --name指定容器名字 -v目录挂载 -p指定端口映射 -e设置mysql参数 -d后台运行 建议映射端口不要用默认3306的,容易被抓鸡挖矿
sudo docker run -p 3603:3306 --name mysql5.7-3603 \
-v /mydata/mysql/log:/var/log/mysql \
-v /mydata/mysql/data:/var/lib/mysql \
-v /mydata/mysql/conf:/etc/mysql \
-e MYSQL_ROOT_PASSWORD=root \
-d mysql:5.7
# 查看docker运行中的容器
sudo docker ps
# 进入mysql容器
sudo docker exec -it mysql5.7-3603 /bin/bash
# 退出
exit;
# 配置mysql
# 因为有目录映射,所以我们可以直接在镜像外执行
vi /mydata/mysql/conf/my.conf
[client]
default-character-set=utf8
[mysql]
default-character-set=utf8
[mysqld]
init_connect='SET collation_connection = utf8_unicode_ci'
init_connect='SET NAMES utf8'
character-set-server=utf8
collation-server=utf8_unicode_ci
skip-character-set-client-handshake
skip-name-resolve
# 重启mysql
sudo docker restart mysql5.7-3603
Redis
如果直接挂载的话docker会以为挂载的是一个目录,所以我们先创建一个文件然后再挂载。
# linux
mkdir -p /mydata/redis/conf
touch /mydata/redis/conf/redis.conf
docker pull redis
# -d 启动命令 启动时用后面的配置文件 建议映射端口不要用默认3306的,容易被抓鸡挖矿
docker run -p 6123:6379 --name redis \
-v /mydata/redis/data:/data \
-v /mydata/redis/conf/redis.conf:/etc/redis/redis.conf \
-d redis redis-server /etc/redis/redis.conf
# 直接进去redis客户端。
docker exec -it redis redis-cli
当前时间:2021.6.21 下载的最新版redis默认开启持久化。如果你们下载的redis无法持久化配置一些内容即可。
# linux下 编辑前面创建的redis.conf
vim /mydata/redis/conf/redis.conf
# 插入下面内容
appendonly yes
# 保存 重启redis 重新进入
docker restart redis
docker exec -it redis redis-cli
设置redis容器在docker启动的时候启动
docker update redis --restart=always
Nginx
docker pull nginx:1.10
# 随便启动一个nginx实例,只是为了复制出配置,放到docker里作为镜像的统一配置
docker run -p 80:80 --name nginx -d nginx:1.10
cd /mydata/nginx
docker container cp nginx:/etc/nginx .
然后在外部 /mydata/nginx/nginx 有了一堆文件
mv /mydata/nginx/nginx /mydata/nginx/conf
# 停掉nginx
docker stop nginx
docker rm nginx
# 创建新的nginx
docker run -p 80:80 --name nginx \
-v /mydata/nginx/html:/usr/share/nginx/html \
-v /mydata/nginx/logs:/var/log/nginx \
-v /mydata/nginx/conf:/etc/nginx \
-d nginx:1.10
# 注意一下这个路径映射到了/usr/share/nginx/html,我们在nginx配置文件中是写/usr/share/nginx/html,不是写/mydata/nginx/html
docker update nginx --restart=always
测试
cd /mydata/nginx/html/
vim index.html
随便写写
测试 http://ip:80
3. 开发环境
1.maven
在settings中配置阿里云镜像,配置profiles为jdk-1.8。
<mirrors>
<mirror>
<id>nexus-aliyun</id>
<mirrorOf>central</mirrorOf>
<name>Nexus aliyun</name>
<url>http://maven.aliyun.com/nexus/content/groups/public</url>
</mirror>
</mirrors>
<profiles>
<profile>
<id>jdk-1.8</id>
<activation>
<activeByDefault>true</activeByDefault>
<jdk>1.8</jdk>
</activation>
<properties>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<maven.compiler.compilerVersion>1.8</maven.compiler.compilerVersion>
</properties>
</profile>
</profiles>
IDEA安装插件lombok,mybatisX。IDEA设置里配置好maven
2. vsCode
Vscode 安装开发必备插件
- Vetur —— 语法高亮、智能感知、Emmet 等 包含格式化功能, Alt+Shift+F (格式化全文),Ctrl+K Ctrl+F(格式化选中代码,两个 Ctrl需要同时按着)
- EsLint —— 语法纠错
- Auto Close Tag —— 自动闭合 HTML/XML 标签
- Auto Rename Tag —— 自动完成另一侧标签的同步修改
- JavaScript(ES6) code snippets — — ES6 语 法 智 能 提 示 以 及 快 速 输 入 , 除 js 外 还 支 持.ts,.jsx,.tsx,.html,.vue,省去了配置其支持各种包含 js 代码文件的时间
- HTML CSS Support —— 让 html 标签上写 class 智能提示当前项目所支持的样式
- HTML Snippets —— html 快速自动补全
- Open in browser —— 浏览器快速打开
- Live Server —— 以内嵌服务器方式打开
- Chinese (Simplified) Language Pack for Visual Studio Code —— 中文语言包
3. Git
下载安装git,去到git bash
Git+码云教程 https://gitee.com/help/articles/4104
# 配置用户名
git config --global user.name "username" # (名字,随意写)
# 配置邮箱
git config --global user.email "55333@qq.com" # 注册账号时使用的邮箱
# 配置ssh免密登录
ssh-keygen -t rsa -C "55333@qq.com"
# 三次回车后生成了密钥:公钥私钥
# 查看密钥
cat ~/.ssh/id_rsa.pub
# 浏览器登录码云后,个人头像上点设置--ssh公钥---随便填个标题---复制
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC6MWhGXSKdRxr1mGPZysDrcwABMTrxc8Va2IWZyIMMRHH9Qn/wy3PN2I9144UUqg65W0CDE/thxbOdn78MygFFsIG4j0wdT9sdjmSfzQikLHFsJ02yr58V6J2zwXcW9AhIlaGr+XIlGKDUy5mXb4OF+6UMXM6HKF7rY9FYh9wL6bun9f1jV4Ydlxftb/xtV8oQXXNJbI6OoqkogPKBYcNdWzMbjJdmbq2bSQugGaPVnHEqAD74Qgkw1G7SIDTXnY55gBlFPVzjLWUu74OWFCx4pFHH6LRZOCLlMaJ9haTwT2DB/sFzOG/Js+cEExx/arJ2rvvdmTMwlv/T+6xhrMS3 553736044@qq.com
# 测试
ssh -T git@gitee.com
4.创建项目
现有项目
项目刚出来的时候老师没把代码放出来,但现在好像把完整版的代码放出来了,所以你可以运行老师给的项目试一下。
但是老师的项目nacos等信息可能没有,还需要你自己搭建。一个好的方式是编译nacos的源码项目到IDEA中。而这种解决方案网上开源的同学们都是这么做的。
除此之外,基本老师给的项目里都全了,你要做的就是改改里面的配置信息等。作为参数,我提供一个别人的链接吧
https://github.com/1046762075/mall,把他拉取到你的本地或者克隆到你的码云上再拉取都可以
但是把项目运行起来可不是简单的事,有很多东西需要自己配置
自己搭建
在码云新建仓库,仓库名gulimall,选择语言java,在.gitignore选中maven(就会忽略掉maven一些个人无需上传的配置文件),许可证选Apache-2.0,开发模型选生成/开发模型,开发时在dev分支,发布时在master分支,创建。
在IDEA中New–Project from version control–git–复制刚才项目的地址,如https://gitee.com/MaxNoob/gulimall.git
项目初始化
new module-Spring Initializer:商品服务、仓储服务、订单服务、优惠券服务、用户服务
共同点:
- 依赖 spring web、openfeign
- 包名com.max
- 模块名
- 优惠券服务:mall-coupon
- 用户服务:mall-member
- 订单服务:mall-order
- 商品服务:mall-product
- 仓储服务:mall-ware
右下角显示了springboot的service选项,选择他
多模块开发
使用父模块对子模块的管理非常方便。
- 父模块pom中的*<properties>*属性会被子模块继承
- 父模块pom中,在*<dependencyManagement>*中可以进行子模块依赖的版本管理,子模块继承父模块之后,提供作用:锁定版本 + 子模块不用再写 version。
- 此外,父模块中可以添加依赖作为全局依赖,子模块自动继承。*<dependencyManagement>外的<dependencies>*中定义全局依赖。
复制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>
<groupId>com.max.gulimall</groupId>
<artifactId>gulimall</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>gulimall</name>
<description>聚合服务</description>
<packaging>pom</packaging>
<modules>
<module>gulimall-product</module>
<module>gulimall-order</module>
<module>gulimall-ware</module>
<module>gulimall-coupon</module>
<module>gulimall-member</module>
</modules>
<properties>
<java.version>1.8</java.version>
<spring.boot.version>2.4.7</spring.boot.version>
<spring-cloud.version>2020.0.3</spring-cloud.version>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>${spring.boot.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<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>
<!-- 这里的依赖会被子模块继承 -->
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
</project>
子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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.max.gulimall</groupId>
<artifactId>gulimall</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<artifactId>gulimall-member</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>gulimall-member</name>
<description>谷粒商城-用户服务</description>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
maven窗口点 + 添加项目下的pom.xml进来,clean一下
修改总项目的.gitignore
,把小项目里的垃圾文件在提交时忽略,比如HELP.md等等
**/mvnw
**/mvnw.cmd
**/.mvn
**/target/
.idea
**/.gitignore
右键unversioned files-add to vcs 添加到文件变更监控列表
idea安装gitee插件
项目结构
提交项目
5. 数据库
数据库文件:https://github.com/FermHan/gulimall 感谢FermHan大佬提供的sql
根据脚本依次创建数据库
mall_oms:订单服务
mall_pms:商品服务
mall_sms:营销服务
mall_ums:用户服务
mall_wms:库存服务
6. 快速开发-人人开源
gitee-人人开源 - https://gitee.com/renrenio
后台管理系统:https://gitee.com/renrenio/renren-fast
后台管理前端:https://gitee.com/renrenio/renren-fast-vue
代码生成器:https://gitee.com/renrenio/renren-generator
克隆项目到本地
git clone https://gitee.com/renrenio/renren-fast.git
git clone https://gitee.com/renrenio/renren-fast-vue.git
git clone https://gitee.com/renrenio/renren-generator.git
6.1 renren-fast
-
删除项目中的.git文件夹,将renren-fast移动到项目目录下,在父POM添加module
<module>renren-fast</module>
-
打开renren-fast/db/mysql.sql,先创建数据库gulimall_admin,然后执行sql
-
修改项目里renren-fast中的application-dev.yml中的数库库配置 - 修改ip、端口号、用户名、密码
-
url: jdbc:mysql://ip:3603/gulimall_admin?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai&useSSL=false username: root password: root
-
浏览器输入http://localhost:8080/renren-fast/ 得到{“msg”:“invalid token”,“code”:401}就代表无误
6.2 renre-fast-vue
安装node:http://nodejs.cn/download/ ,配置npm镜像仓库地址npm config set registry http://registry.npm.taobao.org/
用VSCode打开renren-fast-vue,打开项目控制台输入npm install
拉取依赖,完成后输入npm run dev
运行项目,http://localhost:8001/
6.3 renren-generator
删除里面的.git
文件夹,拖动到idea项目里
父POM添加<module>renren-generator</module>
,刷新maven
修改generator - application.yml
# mysql
spring:
datasource:
type: com.alibaba.druid.pool.DruidDataSource
#MySQL配置
driverClassName: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://ip:port/gulimall_pms?useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=Asia/Shanghai
username: root
password: root
generator.properties
# 主目录
mainPath=com.max
# 包名
package=com.max.gulimall
# 模块名
moduleName=product
# 作者
author=max
#Email
email=759946061@qq.com
#表前缀(类名不会包含表前缀) # 我们的pms数据库中的表的前缀都pms
# 如果写了表前缀,每一张表对于的javaBean就不会添加前缀了
tablePrefix=pms_
运行访问 - http://localhost:80/ 每页显示50,全选后点生成代码,解压复制main到gulimall-product同级目录下
7.4 gulimall-common
创建maven模块 - gulimall-common
POM
<!-- mybatisPLUS-->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.3.2</version>
</dependency>
<!--简化实体类,用@Data代替getset方法-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.8</version>
</dependency>
<!-- httpcomponent包。发送http请求 -->
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpcore</artifactId>
<version>4.4.13</version>
</dependency>
<dependency>
<groupId>commons-lang</groupId>
<artifactId>commons-lang</artifactId>
<version>2.6</version>
</dependency>
把公共的类和依赖放到common模块中,在各个服务POM中添加common依赖即可。
<dependency>
<groupId>com.atguigu.gulimall</groupId>
<artifactId>gulimall-common</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
-
复制renren-fast----utils包下的Query和
PageUtils
、R
、Constant
复制到common项目的java/com.max.common.utils
下。 -
generator逆向生成的controller中带@RequiresPermissions,这是shiro的,我们项目没有用到,所以注释renren-generator\src\main\resources\template/Controller中所有的@RequiresPermissions。
## import org.apache.shiro.authz.annotation.RequiresPermissions;
重新生成代码,复制main下的controller到product中。
common目录
7.5 整合MybatisPlus
common的POM添加依赖
<!-- 数据库驱动 https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.17</version>
</dependency>
<!--tomcat里一般都带-->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.5</version>
<scope>provided</scope>
</dependency>
product添加application.yml
spring:
datasource:
username: root
password: root
url: jdbc:mysql://120.79.0.96:3603/gulimall_pms?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai&useSSL=false
driver-class-name: com.mysql.cj.jdbc.Driver
# MapperScan
# sql映射文件位置
mybatis-plus:
mapper-locations: classpath:/mapper/**/*.xml
global-config:
db-config:
id-type: auto
classpath 和 classpath* 区别:
classpath:只会到你的class路径中查找找文件;
classpath*:不仅包含class路径,还包括jar文件中(class路径)进行查找
classpath*
的使用:当项目中有多个classpath路径,并同时加载多个classpath路径下(此种情况多数不会遇到)的文件,*
就发挥了作用,如果不加*,则表示仅仅加载第一个classpath路径。
主启动类上添加@MapperScan()
@SpringBootApplication
@MapperScan("com.max.gulimall.product.dao")
public class GulimallProductApplication {
public static void main(String[] args) { SpringApplication.run(GulimallProductApplication.class,args);
}
}
测试
@SpringBootTest
class GulimallProductApplicationTests {
@Autowired
private BrandService bs;
@Test
void contextLoads() {
BrandEntity brandEntity = new BrandEntity();
// brandEntity.setName("Apple");
// boolean save = bs.save(brandEntity);
// System.out.println("------添加结果:" + save);
brandEntity.setBrandId(6L);
brandEntity.setName("一加");
boolean update = bs.updateById(brandEntity);
System.out.println("------修改结果:" + update);
}
}
7.6 模块逆向生成crud
按照以上流程,使用generator逆向生成其余模块
Module - database - port
- coupon - sms - 7000
- member - ums - 8000
- order - oms - 9000
- ware - wms - 11000
- product - pms - 10000
7. Nacos
Nacos服务注册和配置中心 = Eureka + Config + Bus
github地址: https://github.com/alibaba/Nacos
Nacos 地址: https://nacos.io/zh-cn/
服务注册与服务框架 | CAP模型 | 控制台管理 | 社区活跃度 |
---|---|---|---|
Eureka | AP高可用 | 支持 | 低(2.x版本闭源) |
Zookeeper | CP一致 | 支持 | 中 |
Consul | CP | 支持 | 高 |
Nacos | AP(可以切换) | 支持 | 高 |
7.1 项目整合
-
https://nacos.io/zh-cn/下载解压nacos,运行bin/startup.cmd
访问 - http://localhost:8848/ 账号&密码nacos
-
在common模块中引入依赖,其他服务引入common即可使用
<dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId> </dependency>
-
在每个模块yml中设置
spring.cloud.nacos.discovery.server-addr=127.0.0.1:8848
和application.name=***
服务命名
7.2 Feign远程调用
Feign是一个声明式的远程调用http客户端。
-
引入openfeign依赖
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-openfeign</artifactId> </dependency>
-
在主启动类上加上注解
@EnableDiscoveryClient
告诉springcloud这是远程调用客户端。/* * 想要远程调用的步骤: * 1 引入openfeign * 2 编写一个接口,接口告诉springcloud这个接口需要调用远程服务 * 2.1 在接口里声明@FeignClient("gulimall-coupon")他是一个远程调用客户端且要调用coupon服务 * 2.2 要调用coupon服务的/coupon/coupon/member/list方法 * 3 开启远程调用功能 @EnableFeignClients,要指定远程调用功能放的基础包 * */ @EnableFeignClients(basePackages="com.atguigu.gulimall.member.feign")//扫描接口方法注解 @EnableDiscoveryClient @SpringBootApplication public class gulimallMemberApplication { public static void main(String[] args) { SpringApplication.run(gulimallMemberApplication.class, args); } }
-
编写接口,请求映射地址写要调用的完整地址(不带ip端口号)
@FeignClient("gulimall-coupon") //告诉spring cloud这个接口是一个远程客户端,要调用coupon服务(nacos中找到),具体是调用coupon服务的/coupon/coupon/member/list对应的方法 public interface CouponFeignService { // 远程服务的url @RequestMapping("/coupon/coupon/member/list")//注意写全优惠券类上还有映射//注意我们这个地方不是控制层,所以这个请求映射请求的不是我们服务器上的东西,而是nacos注册中心的 public R membercoupons();//得到一个R对象 }
这里使用@FeignClient + @RequestMapping构成远程调用的坐标
从nacos里调用指定服务的指定请求获取数据
-
修改CouponController的内容
@RequestMapping("coupon/coupon") public class CouponController { @Autowired private CouponService couponService; @RequestMapping("/member/list") public R membercoupons(){ //全系统的所有返回都返回R // 应该去数据库查用户对于的优惠券,但这个我们简化了,不去数据库查了,构造了一个优惠券给他返回 CouponEntity couponEntity = new CouponEntity(); couponEntity.setCouponName("满100-10");//优惠券的名字 return R.ok().put("coupons",Arrays.asList(couponEntity)); }
-
member中编写一个测试请求
@RestController @RequestMapping("member/member") public class MemberController { @Autowired private MemberService memberService; @Autowired CouponFeignService couponFeignService; @RequestMapping("/coupons") public R test(){ MemberEntity memberEntity = new MemberEntity(); memberEntity.setNickname("会员昵称张三"); R membercoupons = couponFeignService.membercoupons();//假设张三去数据库查了后返回了张三的优惠券信息 //打印会员和优惠券信息 return R.ok().put("member",memberEntity).put("coupons",membercoupons.get("coupons")); }
-
测试 - http://localhost:8000/member/member/coupons
{ "msg":"success", "code":0, "coupons":[ {"id":null,"couponType":null,"couponImg":null,"couponName":"满100-10","num":null,"amount":null,"perLimit":null,"minPoint":null,"startTime":null,"endTime":null,"useType":null,"note":null,"publishCount":null,"useCount":null,"receiveCount":null,"enableStartTime":null,"enableEndTime":null,"code":null,"memberLevel":null,"publish":null} ], "member":{"id":null,"levelId":null,"username":null,"password":null,"nickname":"会员昵称张三","mobile":null,"email":null,"header":null,"gender":null,"birth":null,"city":null,"job":null,"sign":null,"sourceType":null,"integration":null,"growth":null,"status":null,"createTime":null} }
7.3 Nacos配置中心
通过Nacos来管理服务的配置文件(application.properties等),将配置文件保存到Nacos集中管理。
官方教程:https://github.com/alibaba/spring-cloud-alibaba/blob/master/spring-cloud-alibaba-examples/nacos-example/nacos-config-example/readme-zh.md
-
common中引入依赖
<dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId> </dependency>
-
coupon模块resources下创建bootstrap.properties,bootstrap优先级比application高,springboot会先读取bootstrap中的内容
# 改名字,对应nacos里的配置文件名 spring.application.name=gulimall-coupon spring.cloud.nacos.config.server-addr=127.0.0.1:8848
由于优先级问题,先读取bootstrap中的内容,springboot会到nacos中找对应的配置文件
配合@Value注解读取配置文件属性
@RestController @RequestMapping("coupon/coupon") public class CouponController { @Autowired private CouponService couponService; @Value("${coupon.user.name}")//从application.properties中获取//不要写user.name,他是环境里的变量 private String name; @Value("${coupon.user.age}") private Integer age; @RequestMapping("/test") public R test(){ return R.ok().put("name",name).put("age",age); }
-
nacos-配置列表-点击
+
,输入一下内容# gulimall-coupon.properties coupon.user.name="配置中心" coupon.user.age=12
-
测试 - http://localhost:7000/coupon/coupon/test
{"msg":"success","code":0,"name":"配置中心","age":12}
-
实际使用中不会经常重启应用,修改nacos配置文件后,通过@RefreshScope动态更新
@RefreshScope @RestController @RequestMapping("coupon/coupon") public class CouponController { @Autowired private CouponService couponService; @Value("${coupon.user.name}")//从application.properties中获取//不要写user.name,他是环境里的变量 private String name; @Value("${coupon.user.age}") private Integer age; @RequestMapping("/test") public R test(){ return R.ok().put("name",name).put("age",age); }
-
Nacos的配置内容优先于项目本地的配置内容
7.4 配置中心(进阶)
Nacos还可以配置命名空间和分组
-
命名空间:用作配置隔离(一般一个微服务一个命名空间)
-
默认public
-
创建命名空间,会生成对应的唯一ID
-
在bootstrap.properties里指定命名空间id
# 可以选择对应的命名空间 # 写上对应环境的命名空间ID spring.cloud.nacos.config.namespace=b176a68a-6800-4648-833b-be10be8bab00
-
-
group
-
默认分组DEFAULT_GROUP
-
# 更改配置分组 spring.cloud.nacos.config.group=DEFAULT_GROUP
-
-
多配合集
-
将application.yml的内容抽离出来放到nacos中,在bootstrap配置
spring.cloud.nacos.config.extension-configs[]
来指定配置集 -
spring.application.name=gulimall-coupon spring.cloud.nacos.config.server-addr=127.0.0.1:8848 # 可以选择对应的命名空间 # 写上对应环境的命名空间ID spring.cloud.nacos.config.namespace=b176a68a-6800-4648-833b-be10be8bab00 # 更改配置分组 spring.cloud.nacos.config.group=dev #新版本不建议用下面的了 #spring.cloud.nacos.config.ext-config[0].data-id=datasource.yml #spring.cloud.nacos.config.ext-config[0].group=dev #spring.cloud.nacos.config.ext-config[0].refresh=true #spring.cloud.nacos.config.ext-config[1].data-id=mybatis.yml #spring.cloud.nacos.config.ext-config[1].group=dev #spring.cloud.nacos.config.ext-config[1].refresh=true #spring.cloud.nacos.config.ext-config[2].data-id=other.yml #spring.cloud.nacos.config.ext-config[2].group=dev #spring.cloud.nacos.config.ext-config[2].refresh=true spring.cloud.nacos.config.extension-configs[0].data-id=datasource.yml spring.cloud.nacos.config.extension-configs[0].group=dev spring.cloud.nacos.config.extension-configs[0].refresh=true spring.cloud.nacos.config.extension-configs[1].data-id=mybatis.yml spring.cloud.nacos.config.extension-configs[1].group=dev spring.cloud.nacos.config.extension-configs[1].refresh=true spring.cloud.nacos.config.extension-configs[2].data-id=other.yml spring.cloud.nacos.config.extension-configs[2].group=dev spring.cloud.nacos.config.extension-configs[2].refresh=true
-
8. GateWay
8.1 简介
springcloud的gateway
作为网关,是请求流量的入口,通常功能包括路由转发,权限校验,限流控制等。取代了zuul
网关。gateway底层使用高性能的Netty。
官网:https://spring.io/projects/spring-cloud-gateway
参考手册:https://cloud.spring.io/spring-cloud-gateway/2.2.x/reference/html/
三大核心概念:
- Route: The basic building block of the gateway. It is defined by an ID, a destination URI, a collection of predicates断言, and a collection of filters. A route is matched if the aggregate predicate is true.发一个请求给网关,网关要将请求路由到指定的服务。路由有id,目的地uri,断言的集合,匹配了断言就能到达指定位置,
- Predicate断言: This is a Java 8 Function Predicate. The input type is a Spring Framework ServerWebExchange. This lets you match on anything from the HTTP request, such as headers or parameters.就是java里的断言函数,匹配请求里的任何信息,包括请求头等。根据请求头路由哪个服务
- Filter: These are instances of Spring Framework GatewayFilter that have been constructed with a specific factory. Here, you can modify requests and responses before or after sending the downstream request.过滤器请求和响应都可以被修改。
流程图:
客户端发请求给服务端。中间有网关。先交给映射器,如果能处理就交给handler处理,然后交给一系列filer,然后给指定的服务,再返回回来给客户端。
使用:
创建gulimall-gateway模块
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>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.8.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<modelVersion>4.0.0</modelVersion>
<description>API网关</description>
<artifactId>gulimall-gateway</artifactId>
<properties>
<java.version>1.8</java.version>
<spring-cloud.version>Greenwich.SR3</spring-cloud.version>
</properties>
<dependencies>
<!-- 引入sentinel网关限流 -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-sentinel-gateway</artifactId>
<version>2.1.0.RELEASE</version>
</dependency>
<dependency>
<groupId>com.max.gulimall</groupId>
<artifactId>gulimall-common</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</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>
</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>
<repositories>
<repository>
<id>spring-milestones</id>
<name>Spring Milestones</name>
<url>https://repo.spring.io/milestone</url>
</repository>
</repositories>
</project>
application.yml
server:
port: 88
spring:
application:
name: gulimall-gateway
cloud:
nacos:
discovery:
server-addr: 127.0.0.1:8848
bootstrap.properties
spring.application.name=gulimall-gateway
spring.cloud.nacos.config.server-addr=127.0.0.1:8848
spring.cloud.nacos.config.namespace=cfb512d5-492f-45cf-8ef2-c628cc65cefa