1.项目介绍以及分布式框架
从前慢-谷粒商城篇章1_unique_perfect的博客-CSDN博客_从前慢 谷粒商城
2.环境搭建
docker的一些命令总结
docker images #查看已经安装的镜像
docker rmi 镜像名:版本号 #删除指定镜像
systemctl restart docker #重启
systemctl start docker #启动
docker ps #查看正在运行的docker,及其基本信息
docker ps -a #查看所有已经创建的docker
docker rm 容器id|容器名 #删除指定的docker
docker stop 容器id|容器名 #停止指定的docker
docker start 容器id|容器名 #启动指定的docker
docker restart 容器id|容器名 #重启指定的docker
2.1安装docker(CentOS)
1 卸载系统之前的docker
sudo yum remove docker \
docker-client \
docker-client-latest \
docker-common \
docker-latest \
docker-latest-logrotate \
docker-logrotate \
docker-engine
2 设置存储库
sudo yum install -y yum-utils
sudo yum-config-manager \
--add-repo \
https://download.docker.com/linux/centos/docker-ce.repo
3 安装DOCKER引擎
sudo yum install docker-ce docker-ce-cli containerd.io
4 启动Docker.
sudo systemctl start docker
5 配置镜像加速
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
3.2 安装mysql
1 拉去mysql镜像,注意这里的版本号是8.0
docker pull mysql:8.0
2 启动mysql容器
# --name指定容器名字 -v目录挂载 -p指定端口映射 -e设置mysql参数 -d后台运行
docker run --name mysql -v /usr/local/mysql/data:/var/lib/mysql -v /usr/local/mysql/conf:/etc/mysql/conf.d -v /usr/local/mysql/log:/var/log/mysql -e MYSQL_ROOT_PASSWORD=root -p 3306:3306 -d mysql:8.0
查询已经启动的docker:
docker ps
3 进入mysql容器 ( | 是 或者 的意思 )
格式:docker exec -it 容器名称|容器id bin/bash
例子:docker exec -it mysql bin/bash
4.进入mysql的命令行界面
mysql -uroot -proot
安装redis
mkdir -p /usr/local/redis/conf
touch /usr/local/redis/conf/redis.conf //这两个是创建redis配置 映射 文件
docker run -p 6379:6379 --name redis -v /usr/local/redis/data:/data -v /usr/local/redis/conf/redis.conf:/etc/redis/redis.conf -d redis redis-server /etc/redis/redis.conf
如何查看容器名称
方式一:使用docker ps 查看
方式二:在启动时我们命名的名字
关于启动容器的命令说明视频链接
--name指定容器名字
-v目录挂载
-p指定端口映射
-e设置mysql参数
-d后台运行
图中的示例跟我的不一样,具体是按照上面的文本挂载的
3.3创建仓库
在码云新建仓库,仓库名gulimall,选择语言java,在.gitignore选中maven,
许可证选Apache-2.0,开发模型选生产/开发模型,开发时在dev分支,
发布时在master分支,创建如图所示
3.4 新建项目并创建出以下服务模块
1.使用git导入项目到idea中
2.到仓库中复制地址
3.粘贴
4.这样就导入成功
5.创建以下模块
商品服务product
存储服务ware
订单服务order
优惠券服务coupon
用户服务member
每个模块导入web和openFeign 如下图所示
6.创建父模块:在gulimall中创建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.atguigu.gulimall</groupId>
<artifactId>gulimall</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>gulimall</name>
<description>谷粒商城-聚合服务</description>
<packaging>pom</packaging>
<modules>
<module>gulimall-coupon</module>
<module>gulimall-member</module>
<module>gulimall-order</module>
<module>gulimall-product</module>
<module>gulimall-ware</module>
</modules>
</project>
7.在maven中刷新一下,guilimall后面就会出现root,如果没有点+号,导入进来
8.修改总项目的.gitignore,把小项目里的垃圾文件在提交的时候忽略掉
target/
pom.xml.tag
pom.xml.releaseBackup
pom.xml.versionsBackup
pom.xml.next
release.properties
dependency-reduced-pom.xml
buildNumber.properties
.mvn/timing.properties
.mvn/wrapper/maven-wrapper.jar
**/mvnw
**/mvnw.cmd
**/.mvn
**/target
.idea
**/.gitignore
**/README.md
9.预览提交的文件
9.1首先设置里关闭
9.2commit
10.刷新码云就能看到新提交的数据
3.5数据库初始化,人人开源搭建后台管理系统/如何提取公共依赖
4.逆向工程
product模块
4.1下载generager renren-generator: 人人开源项目的代码生成器,可在线生成entity、xml、dao、service、vue、sql代码,减少70%以上的开发任务
1.删除文件中的.git
2.打开项目根目录,将文件粘贴进去(注意:不要直接导入)
3.在gulimall的pom.xml中加入renren-generator
然后刷新
4.修改renren-generator中的 .yml配置文件
4.修改renren-generator中的,properties文件,对于每一个模块都这么配置
在renren-generator得resources下的template下的controller模板中将@requiresPermissions先注释
然后删除依赖
5.执行gennerator
6.打开localhost:80端口
7.下载
8.解压文件,将文件中的main,粘贴到各个对应的模块中,注意一定要从文jian夹目录中粘贴不要从idea中粘贴
9.粘贴之后,我们发现,逆向工程给我们自动生产的代码,会用到很多依赖,这时候我们就要添加依赖,所哟我们创建一个模块gulimall-common,我们把每个微服务里公共的类和依赖放到common里,为什么要创建gulimall-common这个包呢?
在gulimall 的pom.xml中也自动添加了<module>gulimall-common</module>
在common项目的pom.xml(我们把每个微服务里公共的类和依赖放到common里。)中添加
<!-- mybatisPLUS 针对dao层报错-->
<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包https://mvnrepository.com/artifact/org.apache.httpcomponents/httpcore -->
<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>
然后在product项目中的pom.xml中加入下面内容
//小技巧,先写<artifactId>gulimall-common</artifactId>,然后<groupId>com.atguigu.gulimall</groupId>自动跳出来
<dependency>
<groupId>com.atguigu.gulimall</groupId>
<artifactId>gulimall-common</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
为什么要创建gulimall-common这个包呢?
因为generator帮我的创建得公共函数和依赖都在这个包里
对应了绿框里的
10.接下来就是测试product模块,完善product模块
1.整合mybatis-plus-因为所有模块都会用到mysql,所以这个依赖写在common中
<!-- mybatisPLUS-->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.3.2</version>
</dependency>
2.配置
①配置数据源 --参https://baomidou.com/pages/226c21/#%E6%B7%BB%E5%8A%A0%E4%BE%9D%E8%B5%96
Ⅰ. 数据库依赖-因为所有模块都会用到mysql,所以这个依赖写在common中
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.28</version>
</dependency>
Ⅱ.编写配置文件-application.yml
# DataSource Config
spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://192.168.142.128:3306/gulimall-pms?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=utf-8&zeroDateTimeBehavior=convertToNull&useSSL=false&allowPublicKeyRetrieval=true
username: root
password: root
②配置mybatis-plus -配置主键类型,详见mybatis @TableId 注解
mybatis-plus:
global-config:
db-config:
id-type: auto
server:
port: 10000
其他模板的一些差别配置
coupon : 端口是7000
member :端口8000
order :端口9000
ware :端口11000
4.springcloudAlibaba
4.1安装及使用注册功能
结合SpringCloud Alibaba,我们最终的技术搭配方案:
SpringCloud Alibaba.- Nacos.:注册中心(服务发现/注册)
SpringCloud Alibaba- Nacos.:配置中心(动态配置管理)
SpringCloud- Ribbon:负载均衡
Springcloud-Feign:声明式HTTP客户端(调用远程服务)
Springcloud Alibaba- Sentinel:服务容错(限流、降级、熔断)
Springcloud-Gateway: API网关(webflux,编程模式)
Springcloud- Sleuth:调用链监控
SpringCloud Alibaba-Seata:原Fescar,即分布式事务解决方案
解读:
一.步骤一,引入依赖
二.注册nacos,作为我们的配置中心和注册中心
1.下载nacos
2.启动nacos :在bin目录下运行cmd,然后启动命令:---->startup.cmd -m standalone,这是单机配置,默认启动是集群
3.loaclhost:8848/nacos 进入页面就是安装成功
具体注册操作:红色部分是nacos需要的操作
先了解一下 Spring Cloud 应用如何接入 Nacos Discovery。
1 首先,修改 common中的pom.xml 文件,引入 Nacos Discovery Starter。-因为每一个模块都要注册进nacos,所以写在common中
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>2 在应用的common中的application.yml 配置文件中配置 Nacos Server 地址和微服务名称
spring:
application:
name: gulimall-coupon #这对应的是各个微服务的名字,也是注册进nacos的别名,这里名字统一
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://192.168.1.103:3306/gulimall_sms?useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=Asia/Shanghai
username: root
password: root
cloud:
nacos:
discovery:
server-addr: 127.0.0.1:8848 #这是nacos的地址mybatis-plus:
mapper-locations: classpath:/mapper/**/*.xml
global-config:
db-config:
id-type: autoserver:
port: 70003 使用 @EnableDiscoveryClient 注解开启服务注册与发现功能
@SpringBootApplication
@EnableDiscoveryClient
public class GulimallCouponApplication {public static void main(String[] args) {
SpringApplication.run(GulimallCouponApplication.class, args);
}}
5 访问http://127.0.0.1:8848/nacos/ 账号密码nacos
出现如下页面,则表示访问成功
4.2 测试member和coupon的远程调用- 使用openFeign来进行远程调用
远程调用总结
**
想要远程调用别的服务
1) 、 引入open-feign依赖
2)、编写一个接口,告诉SpringCloud这个接口需要调用远程服务
声明接口的每一个方法都是调用哪个远程服务的那个请求*
3)、 开启远程调用功能
想要获取当前会员领取到的所有优惠券。先去注册中心找优惠券服务,
注册中心调一台优惠券服务器给会员,会员服务器发送请求给这台优
惠券服务器,然后对方响应。Feign与注册中心
spring cloud feign声明式远程调用
feign是一个声明式的HTTP客户端,他的目的就是让远程调用更加简单。
给远程服务发的是HTTP请求。1 会员服务想要远程调用优惠券服务,只需要给会员服务里引入
openfeign依赖,他就有了远程调用其他服务的能力,需要使用openfeign的模块都要引入。 问题:为什么不写在common中<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-loadbalancer</artifactId> <version>2.2.2.RELEASE</version> </dependency> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId> <exclusions> <exclusion> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-ribbon</artifactId> </exclusion> </exclusions> </dependency>因为版本问题会出现FeignService无法注入的问题,需要在common的pom中加入
2.在couponControllser中添加方法/** * 功能描述: 学习一下这个请求地址,这个请求的意思是获取指定用户的优惠券, * 但是这是测试的,我们不从数据库中调用,直接创建,将就一下 * */ @RequestMapping("/member/list") public R membercoupons(){ CouponEntity couponEntity1 = new CouponEntity(); couponEntity1.setCouponName("满1000减100000"); CouponEntity couponEntity2 = new CouponEntity(); couponEntity2.setCouponName("满1000减10"); //连续的函数调用 return R.ok().put("coupons",Arrays.asList(couponEntity1,couponEntity2)); }3.在member的配置类上加注解@EnableFeignClients(basePackages="com.yxj.gulimall.member.feign"), 告诉spring这里面是一个远程调用客户端,member要调用的接口
4.在memeber模块中新建一个feign,以后所有的调用都放在这个文件夹下 ,
新建接口 CouponFeignService 取名方式 被调用的模块名+FeignService
写方法
5.在MEmberController
@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")); };6.测试
4.3nacos配置中心-以coupon为例
比如 以前在application.yml中配置了 car.name=lixiang, 然后在类中使用@Value调用,但是如果配置一更换,需要重启服务很麻烦
可以参考官网,如下
总结
步骤一:导入依赖
步骤二:配置 Nacos Config 元数据
步骤三:需要给配置中心默认添加一个数据集(Data Id)微服务的名字.properties(比如gulimall-coupon.properties )
步骤四:在页面的配置文件((比如gulimall-coupon.properties ))中添加配置
步骤五:这样就可以动态获取配置,还要加上注解
@RefreshScope:动态获取并刷新配置,写在调用了配置的类上
@Value("${配置名}"):获取配置
如果配置中心和当前应用的配置文件中都配置了相同的项,优先使用配置中心的配置
首先,修改 pom.xml 文件,引入 Nacos Config Starter。因为所有模块都需要,所以我们在common中配置,引入bootstrap
<dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId> </dependency> <!-- https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-starter-bootstrap --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-bootstrap</artifactId> <version>3.0.1</version> </dependency>
在应用的 /src/main/resources下创建bootstrap.properties 配置文件中,然后配置 Nacos Config 元数据 springboot优先读取bootstrap.properties配置文件,早于application
#微服务的名字后面不能有空格 spring.application.name=gulimall-coupon #nacos的地址:端口号 后面不能有空格 spring.cloud.nacos.config.server-addr=127.0.0.1:8848
3.启动之后,发现DataId
4.登录nacos localhost:8848,然后按步骤
在Data ID处填上,之前启动微服务后,控制台里的Data ID加上 .properties,注意配置格式的选择
如果要编辑:
4.就可以获取动态配置了,要加两个注解
@RefreshScope(proxyMode = ScopedProxyMode.DEFAULT)
@Value
5.测试
4.4nacos配置中心进阶
1.命名空间:配置隔离
默认:public(保留空间);默认新增的所有配置都在public空间。
1、开发,测试,生产:利用命名空间来做环境隔离。
注意。在bootstrap.properties;配置上,需要使用哪个命名空间下的配置,
spring.cloud.nacos.config.namespace=9de62e44-cd2a-4a82-bf5c-95878bd5e871
2、每一个微服务之间互相隔离配置,每一个微服务都创建自己的命名空间,只加载自己命名空间下的所有配置
具体操作:
如果在bootstrap.properties没有指明命名空间
那么默认:public(保留空间);默认新增的所有配置都在public空间。
如何使用命名空间
①新增命名空间
创建成功
在dev配置环境中添加微服务模块
那如何让coupon微服务模块,使用这个指定的dev环境而不是默认的public环境呢?
就是将这个很长的id复制到bootstrap.properties的namespace中,coupon模块就知道要用dev这个配置环境
当然也可以直接克隆,这样就不用重新写一遍了
除了可以用这样方法配置开发环境,测试环境,我们也可以给每个模块分别创建一个自己的环境 ,这应该是用的最多的吧
2.配置分组
除了使用命名分组,也可以使用配置分组
使用场景:我们给couppon模块,创建自己的命名空间gulimall-coupon.preoperties,然后再在这个命名空间中创建dev,test等分组,这样coupon就可以独立灵活地切换配置环境
具体操作:这里用的克隆比较方便,也可以在coupon命名空间里自己创建,group名字改一下就行,默认是DEFAULT_GROUP
3.加载多配置表
注意区分一下gulimall-coupon.properties和多配置表的区别,gulimall-coupon.properties是项目一启动就去nacous配置中心读取的(如果加入了bootstrap依赖)
如果所有的配置我们都放在properties.yml文件中,我们到时候维护就很麻烦,所以我们可以将这一大堆的配置分表放进nacos的配置中心
①我们看一下原来的yml文件,打算分成三个表
②首先提取datasourece的配置
③然后一次提取mybaits、other,效果如图
④nacos配置中心配置完成之后,我们就要去模块中配置
启动微服务之后,在控制台,我们可以看到读取的nacos执行的四个配置 ,但是都在原本的Data ID前加了bootstrapProperties-
注意,如果上面四个地方的config.group指定的分组不存在,那么nacos就会去读取模块中的配置文件(比如application.yml中的信息)
网关GateWay
环境一:假如我们现在要用后台调用商品服务,做CRUD,但此时改微服务宕机,这时候我们需要手动重新分配一个微服务;
我们就需要让后台请求先经过网关,网关帮我们动态地路由到各个服务,感知某个服务的上下线,帮我们把请求正确地路由到指定位置
环境二:我们想对每一个微服务进行限流,监控,日志输出,每个微服务都写这些功能,就太麻烦,网关帮我们做
网关是干嘛的:当我们的请求到达网关,网关先利用断言,判断请求是否符合某个路由规则,如果符合,就路由到指定的服务端,但在路由到服务器之前,需要经过一些列的过滤器
官网地址 :
创建网关
步骤一:建立一个微服务:gulimall-gateway,并且导入gateway依赖
步骤二:在gateway的pom中加入common依赖
步骤三:开启服务注册发现,注册进nacos (①@EnableDiscoveryClient ②配置文件中写sever-addr和application.name)
步骤四:注册进配置中心
步骤五:gateway初体验-详情看官网Spring Cloud Gateway
我们想通过 localhost:80/hello?url=baidu 访问百度
localhost:80/hello?url=qq 访问qq
效果:
如果启动出现问题:
报错的原因是,我们导入common包,common中有数据库的依赖。所以我们要排除数据库的包
解决方法:
@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class})