一、项目简介
本项目适合人群:学过ssm是必须的。项目里有mybatis-plus和springcloud的内容,你可以用本项目来做实践,也可以利用本项目初识cloud,但最好还是对微服务有一定了解。
下好了vargant,如果安装centos7很慢,可以用下面的连接替换老师初始化的那一步:vagrant init centos7 https://mirrors.ustc.edu.cn/centos-cloud/centos/7/vagrant/x86_64/images/CentOS-7.box
,然后在执行vagrant up ,就很快了,这个是国内的镜像地址。vagrant up,中间执行出现异常的话,多试几次。
二、分布式基础概念
1 微服务
拒绝大型单体应用,基于业务边界进行服务微化拆分,各个服务独立部署运行
2.集群,分布式,节点
集群是个物理形态,分布式是个工作方式。
只要是一堆机器,就可以叫集群
分布式是指将不同业务分布在不同的地方,
集群是指将几台服务器集中在一起,实现同一业务
3 远程调用:在分布式系统中,各个服务可能处于不同主机,但是服务之间不可避免的相互调用,我们成为远程调用
springcloud中使用HTTP+JSON的方式完成远程调用
4.负载均衡:轮询,最小连接数,散列
5 服务注册/发现&注册中心
A服务调用B服务,A服务并不知道B服务当前在哪几台服务器有,那些是正常的,那些服务已经下线。解决这个问题可以引入注册中心。
配置中心用来集中管理微服务的配置信息。
服务熔断&服务降级
rpc远程调用情景:
订单服务 --> 商品服务 --> 库存服务
库存服务出现故障导致响应慢,导致商品服务需要等待,可能等到10s后库存服务才能响应。库存服务的不可用导致商品服务阻塞,商品服务等的期间,订单服务也处于阻塞。一个服务不可用导致整个服务链都阻塞。如果是高并发,第一个请求调用后阻塞10s得不到结果,第二个请求直接阻塞10s。更多的请求进来导致请求积压,全部阻塞,最终服务器的资源耗尽。导致雪崩
在微服务架构中,微服务之间通过网络进行通信,存在相互依赖,当其中一个服务不可用时,有可能会造成雪崩效应要防止这样的情况,必须要有容错机制来保护服务。
1)服务熔断:设置服务的超时,当被调用的服务经常失败达到某个阀值,我们可以开启断路保护机制,后来的请求不再去调用这个服务,本地直接返回默认的数据
指定超时时间,库存服务3s没有响应就超时,如果经常失败,比如10s内100个请求都失败了。开启断路保护机制,下一次请求进来不调用库存服务了,因为上一次100%错误都出现了,我们直接在此中断,商品服务直接返回,返回一些默认数据或者null,而不调用库存服务了,这样就不会导致请求积压。
2)服务降级:当系统处于高峰期,系统资源紧张,我们可以让非核心业务降级运行。降级:某些服务不处理,或者简单处理【抛异常、返回null、调用Mock数据,调用Fallback处理逻辑】
API网关
客户端发送请求到服务器路途中,设置一个网关,请求都先到达网关,网关对请求进行统一认证(合法非法)和处理等操作。他是安检。
在微服务架构中,API gateway作为整体架构的重要组件,它抽象了微服务中都需要的公共功能,同时提供了客户端负载均衡,服务自动熔断,灰度发布,统一认证,限流流控,日志统计等丰富的功能,帮助我们解决很多API管理难题。
前后分离开发,分为内网部署和外网部署,外网是面向公众访问的,部署前端项目,可以有手机APP,电脑网页;内网部署的是后端集群,前端在页面上操作发送请求到后端,在这途中会经过Nginx集群,Nginx把请求转交给API网关(springcloud gateway)(网关可以根据当前请求动态地路由到指定的服务,看当前请求是想调用商品服务还是购物车服务还是检索),从路由过来如果请求很多,可以负载均衡地调用商品服务器中一台(商品服务复制了多份),当商品服务器出现问题也可以在网关层面对服务进行熔断或降级(使用阿里的sentinel组件),网关还有其他的功能如认证授权、限流(只放行部分到服务器)等。
到达服务器后进行处理(springboot为微服务),服务与服务可能会相互调用(使用OpenFeign组件),有些请求可能经过登录才能进行(基于OAuth2.0的认证中心。安全和权限使用springSecurity控制)
服务可能保存了一些数据或者需要使用缓存,我们使用redis集群(分片+哨兵集群)。持久化使用mysql,读写分离和分库分表。
服务和服务之间会使用消息队列(RabbitMQ),来完成异步解耦,分布式事务的一致性。有些服务可能需要全文检索,检索商品信息,使用ElaticSearch。
服务可能需要存取数据,使用阿里云的对象存储服务OSS。
项目上线后为了快速定位问题,使用ELK对日志进行处理,使用LogStash收集业务里的各种日志,把日志存储到ES中,用Kibana可视化页面从ES中检索出相关信息,帮助我们快速定位问题所在。
在分布式系统中,由于我们每个服务都可能部署在很多台机器,服务和服务可能相互调用,就得知道彼此都在哪里,所以需要将所有服务都注册到注册中心。服务从注册中心发现其他服务所在位置(使用阿里Nacos作为注册中心)。
每个服务的配置众多,为了实现改一处配置相同配置就同步更改,就需要配置中心,也使用阿里的Nacos,服务从配置中心中动态取配置。
服务追踪,追踪服务调用链哪里出现问题,使用springcloud提供的Sleuth、Zipkin、Metrics,把每个服务的信息交给开源的Prometheus进行聚合分析,再由Grafana进行可视化展示,提供Prometheus提供的AlterManager实时得到服务的告警信息,以短信/邮件的方式告知服务开发人员。
还提供了持续集成和持续部署。项目发布起来后,因为微服务众多,每一个都打包部署到服务器太麻烦,有了持续集成后开发人员可以将修改后的代码提交到github,运维人员可以通过自动化工具Jenkins Pipeline将github中获取的代码打包成docker镜像,最终是由k8s集成docker服务,将服务以docker容器的方式运行。
反映了需要创建的微服务以及相关技术。
前后分离开发。前端项目分为admin-vue(工作人员使用的后台管理系统)、shop-vue(面向公众访问的web网站)、app(公众)、小程序(公众)
商品服务:商品的增删改查、商品的上下架、商品详情
支付服务
优惠服务
用户服务:用户的个人中心、收货地址
仓储服务:商品的库存
秒杀服务:定时任务与redis
订单服务:订单增删改查、验价、幂等性token
检索服务:商品的检索ES
中央认证服务:登录、注册、单点登录、社交登录
购物车服务:redis
后台管理系统:添加优惠信息等
三、linux环境搭建
下载&安装 VirtualBox https://www.virtualbox.org/,要开启 CPU 虚拟化
visualBox进行安装需要cpu开启虚拟化,在开机启动的时候设置主板,CPU configuration,然后点击Intel Vitualization Technology。重启电脑
普通安装linux虚拟机太麻烦,可以利用vagrant可以帮助我们快速地创建一个虚拟机。主要装了vitualbox,vagrant可以帮助我们快速创建出一个虚拟机。他有一个镜像仓库。
去https://www.vagrantup.com/ 下载vagrant安装,安装后重启系统。cmd中输入vagrant有版本代表成功了。
输入vagrant init centos/7,即可初始化一个centos7系统。(注意这个命令在哪个目录下执行的,他的Vagrantfile就生成在哪里)
vagrant up启动虚拟机环境。
启动后出现default folder:/cygdrive/c/User/… =>/vagrant。然后ctrl+c退出
前面的页面中有ssh账号信息。vagrant ssh 就会连上虚拟机。可以使用exit退出
下次使用也可以直接vagrant up直接启动,但要确保当前目录在C:/用户/ 文件夹下,他下面有一个
Vagrantfile
,不过我们也可以配置环境变量。启动后再次
vagrant ssh
连上即可
不过他使用的网络方式是网络地址转换NAT(端口转发),如果其他主机要访问虚拟机,必须由windows端口如3333发给虚拟机端口如3306。这样每在linux里安一个软件都要进行端口映射,不方便,(也可以在virualBox里挨个设置)。我们想要给虚拟机一个固定的ip地址,windows和虚拟机可以互相ping通
visualBox的网络模式可以参考:https://mp.weixin.qq.com/s?__biz=MzI5MDg4ODEzOA==&mid=2247488277&idx=1&sn=012c33bec2984a61850b30b1bb270812&scene=21#wechat_redirect
方式1是在虚拟机中配置静态ip。
方式2:更改Vagrantfile更改虚拟机ip,修改其中的config.vm.network "private_network",ip:"192.168.56.10",这个ip需要在windows的ipconfig中查到vitualbox的虚拟网卡ip,然后更改下最后一个数字就行(不能是1,1是我们的主机)。配置完后vagrant reload重启虚拟机。在虚拟机中ip addr就可以查看到地址了。互相ping也能ping通。
关掉防火墙,VirualBox中第一个网卡设置NAT,第二个网卡设置仅主机
如果ping不了baidu
cd /etc/sysconfig/network-scripts
ls 一般有ifcfg-eth0 1
ip addr 看哪个网格是192.168.56网段,然后vim他
vim ifcfg-eth1 加入
GATEWAY=192.168.56.1
DNS1=114.114.114.114
DNS2=8.8.8.8
service network restart
默认只允许ssh登录方式,为了后来操作方便,文件上传等,我们可以配置允许账号密码登录
vim /etc/ssh/sshd_config
修改
PasswordAuthentication yes
重启
service sshd restart
账号root
密码vagrant
配置源
# 备份原yum源
mv /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.repo.backup
# 使用新yum源
curl -o /etc/yum.repos.d/CentOS-Base.repo http://mirrors.163.com/.help/CentOS7-Base-163.repo
# 生成缓存
yum makecache
Install Docker Engine on CentOS | Docker Documentation虚拟机安装docker
Install Docker Engine on CentOS | Docker Documentation
#卸载系统之前的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-docker
用docker安装上mysql,去docker仓库里搜索mysql
sudo docker pull mysql:5.7
# --name指定容器名字 -v目录挂载 -p指定端口映射 -e设置mysql参数 -d后台运行
sudo docker run -p 3306:3306 --name mysql \
-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
su root 密码为vagrant,这样就可以不写sudo了
[root@localhost vagrant]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
6a685a33103f mysql:5.7 "docker-entrypoint.s…" 32 seconds ago Up 30 seconds 0.0.0.0:3306->3306/tcp, 33060/tcp mysql
# 进入已启动的容器
docker exec -it mysql bin/bash
# 退出进入的容器
exit;
因为有目录映射,所以我们可以直接在镜像外执行
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
docker restart mysql
如何通过其他工具链接ssh
修改/etc/ssh/sshd_config
修改 PasswordAuthentication yes
systemctl restart sshd.service 或 service sshd restart
连接192.168.56.10:22端口成功,用户名root,密码vagrant
也可以通过vagrant ssh-config查看ip和端口,此时是127.0.0.1:2222
Redis
如果直接挂载的话docker会以为挂载的是一个目录,所以我们先创建一个文件然后再挂载,在虚拟机中。
# 在虚拟机中
mkdir -p /mydata/redis/conf
touch /mydata/redis/conf/redis.conf
docker pull redis
docker run -p 6379: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
默认是不持久化的。在配置文件中输入appendonly yes,就可以aof持久化了。修改完docker restart redis,docker -it redis redis-cli
vim /mydata/redis/conf/redis.conf
# 插入下面内容
appendonly yes
保存
docker restart redis
设置redis容器在docker启动的时候启动
docker update redis --restart=always
安装nginx docker
docker pull nginx:1.10
# 随便启动一个nginx实例,只是为了复制出配置,放到docker里作为镜像的统一配置
docker run -p 80:80 --name nginx -d nginx:1.10
# 把nginx里的东西复制出来
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://192.168.56.10:80
四、IDEA开发环境
maven
在settings中配置阿里云镜像,配置jdk1.8。这个基本都配置过,不贴了
IDEA安装插件lombok,mybatisX。IDEA设置里配置好maven
vsCode设置
下载vsCode用于前端管理系统。在vsCode里安装插件。
Auto Close Tag
Auto Rename Tag
Chinese
ESlint
HTML CSS Support
HTML Snippets
JavaScript ES6
Live Server
open in brower
Vetur
五、git代码相关
# 配置用户名
git config --global user.name "username" //(名字,随意写)
# 配置邮箱
git config --global user.email "[email protected]" // 注册账号时使用的邮箱
# 配置ssh免密登录
ssh-keygen -t rsa -C "[email protected]"
三次回车后生成了密钥:公钥私钥
cat ~/.ssh/id_rsa.pub
也可以查看密钥
浏览器登录码云后,个人头像上点设置--ssh公钥---随便填个标题---复制
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC6MWhGXSKdRxr1mGPZysDrcwABMTrxc8Va2IWZyIMMRHH9Qn/wy3PN2I9144UUqg65W0CDE/thxbOdn78MygFFsIG4j0wdT9sdjmSfzQikLHFsJ02yr58V6J2zwXcW9AhIlaGr+XIlGKDUy5mXb4OF+6UMXM6HKF7rY9FYh9wL6bun9f1jV4Ydlxftb/xtV8oQXXNJbI6OoqkogPKBYcNdWzMbjJdmbq2bSQugGaPVnHEqAD74Qgkw1G7SIDTXnY55gBlFPVzjLWUu74OWFCx4pFHH6LRZOCLlMaJ9haTwT2DB/sFzOG/Js+cEExx/arJ2rvvdmTMwlv/T+6xhrMS3 [email protected]
# 测试
ssh -T [email protected]
测试成功,就可以无密给码云推送仓库了