谷粒商城——基础篇

一、分布式基础概念

1、微服务

微服务架构风格就是把单独的应用程序构造为一种松耦合服务,每个小服务运行在自己的进程中,并使用轻量级机制通信,通常是httpApi,这些服务围绕业务能力来构建,并通过完全自动化部署机制来独立部署。这些服务可以使用不同编程语言,以及不同存储技术,并保持最低限度的集中式管理
简而言之:拒绝大型单体应用,基于业务边界进行服务微化拆分,各个服务独立部署运行

2、集群&分布式

集群:同一个业务,部署在多个服务器上。解决的是服务器的压力问题,当一台服务器不足以支撑所有的请求,就需要考虑集群服务器,多台服务器共同提供服务。它是一种物理形态,广义上来讲,只要是一堆机器都可以叫集群,他们是否一起协作干活,这个谁也不知道
分布式:一个业务拆分成多个子业务,部署在不同的服务器。解决的一个大项目的臃肿问题,它把一个大的业务拆分成若干份小业务。是一种工作方式。

例如:京东是一个分布式系统,众多业务运行在不同的机器上,所有业务构成一个大型的业务集群。每个小的业务,比如用户系统,访问压力大的时候一台服务器是不够的,我们就需要将用户系统部署到多个服务器,也就是可以将每个业务系统集群化

3、远程调用

在分布式系统中,各个服务可能处于不同主机,但服务之间不可避免的相互调用,我们称之为远程调用。springCloud使用http+json的方式完成远程调用。
好处:跨平台,json在任意平台都可以使用。http请求在php、c++等任意系统都可以接收和发送

4、负载均衡

在这里插入图片描述

在分布式系统中,A服务需要调用B服务,B服务在多台机器中存在,A调用任意一个服务器均可完成,为了使每个服务不要太忙也不要太闲,我们可以负载均衡的调用每一个服务器,提高网站的健壮性。
常见的负载均衡算法:

  • 轮询:为第一个请求分发到第一台后端服务器,然后按顺序往后依次选择,直到最后一个,然后循环
  • 最小连接:优先选择连接数最少,也就是压力最小的后端服务器,在会话较长的情况下可以考虑采取这种方式
  • 散列:根据请求源的ip的散列(hash)来选择要转发的服务器。这种方式可以一定程度上保证特定用户能连接到相同的服务器。如果你的应用需要处理状态而要求用户能连接到和之前相同的服务器,可以考虑采取这种方式

5、springCloud涉及到的微服务组件:

在这里插入图片描述

  • 服务注册/发现&注册中心:
    A服务调用B服务,A服务并不知道B服务当前在哪几台服务器有,哪些是正常的,哪些服务已经下线。解决这个问题可以引入注册中心。如果某些服务下线,其他人可以实时的感知其他服务的状态,从而避免调用不可用的服务。配置中心。
  • 配置中心
    每个服务最终都有大量的配置,并且每个服务都可能部署在多台服务器上,我们经常需要变更配置,所以我们可以让每个服务从配置中心获取自己的配置。配置中心就是用来集中管理微服务的配置信息
  • 服务熔断&服务降级:
    在微服务架构中,微服务之间通过网络进行通信,存在相互依赖,当其中一个服务不可用时,会造成雪崩效应。要防止这样的情况,必须要有容错机制来保护服务。
    例如:订单服务–>商品服务–>库存服务;
    库存服务出现故障导致响应慢,导致商品服务需要等待,可能等到10s后库存服务才能响应,库存服务的不可用导致商品服务阻塞,商品服务等待期间,订单服务也处于阻塞。一个服务不可用导致整个服务链都阻塞。如果高并发,第一个请求调用后阻塞10s得不到结果,第二个请求直接阻塞10s,更多的请求进来导致请求积压,全部阻塞,最终服务器的资源耗尽。导致雪崩。解决方案:
    1、服务熔断:指定超时时间,如库存服务3s没有响应就超时,如果经常失败,比如10s内100个请求都失败了。开启断路保护机制,下次请求进来不调用库存服务了,因为上一次100%错误的出现,我们直接在此中断,商品服务直接返回一些默认数据或null,而不调用库存服务了,这样就不会导致请求积压
    2、服务降级:在运维期间,当系统处于高峰期,系统资源紧张,我们可以让非核心业务降级运行。降级:服务不处理或简单处理【抛异常、返回null、调用Mock数据、调用Fallback处理逻辑】
  • API网关
    客户端发送请求到服务器路途中,设置一个网关,请求先到达网关,网关对请求进行统一认证(合法非法)和处理等操作,他是安检。在微服务架构中,API gateway作为整体架构的重要组件,它抽象了微服务中都需要的公共功能,同时提供了客户端负载均衡、服务自动熔断、灰度发布、统一认证、限流控制、日志统计等丰富的功能,帮我们解决了很多API管理难题

二、项目介绍

1、微服务架构

谷粒商城微服务架构图

采用前后端分离开发,分为内网部署和外网部署,外网是面向公众访问的,部署前端项目,可以有手机APP、电脑网页;内网部署的是后端集群,前端在页面上操作发送请求到后端,在这途中会经过nginx集群,nginx把请求转交给API网关(springcloud gateway)(网关可以根据当前请求动态地路由到指定的服务,看当前请求是想调商品服务还是购物车服务还是检索),从路由过来如果请求很多,可以负载均衡地调用商品服务器中一台(商品服务复制了多份),当商品服务器出现问题也可以在网关层对服务进行熔断或降级(使用阿里的sentinel组件),网关还有其他的功能如认证授权、限流(只放行部分到服务器)等。

到达服务器后进行处理(springboot为微服务),服务与服务可能会相互调用(使用feign组件),有些请求可能经过登陆才能进行(基于OAuth2.0的认证中心。安全和权限使用springSecurity控制)

服务可能保存了一些数据或者需要使用缓存,我们使用redis集群(分片+哨兵集群)。持久化使用mysql,读写分离和分库分表

服务和服务之间使用消息队列(RabbitMQ),来完成异步解耦,分布式事务的一致性。有些服务可能需要全文检索,检索商品信息,使用ElasticSearch。

服务可能需要存取数据,使用阿里云的对象存储服务OSS。

项目上线后为了快速定位问题,使用ELK对日志进行处理,使用LogStash收集业务里的各种日志,把日志存储到ES中,用Kibana可视化页面从ES中检索出相关信息,帮助我们快速定位问题所在。

在分布式系统中,由于我们每个服务都可能部署在很多台机器,服务和服务可能相互调用,就得知道彼此都在哪里,所以需要将所有服务都注册到注册中心,服务从注册中心发现其他服务所在位置(使用Nacos作为注册中心)。

每个服务的配置众多,为了实现改一处配置相同配置就同步更改,就需要配置中心,也使用阿里的Nacos,服务从配置中心动态取配置。

服务追踪,追踪服务调用链哪里出现问题,使用springcloud提供的Sleuth、Zipkin、Metrics,把每个服务的信息交给开源的Prometheus进行聚合分析,再由Grafana进行可视化展示,提供Prometheus提供的AlterManager实时得到服务的告警信息,以短信/邮件的方式告知服务开发人员。

还提供了持续集成和持续部署,项目发布起来后,因为微服务众多,每一个都打包部署到服务器太麻烦,有了持续集成后开发人员可以将修改后的代码提交到github,运维人员可以通过自动化工具Jenkins Pipeline将github中获取的代码打包成docker镜像,最终是由k8s集成docker服务,将服务以docker容器的形式运行

2、微服务划分

在这里插入图片描述
反映了需要创建的微服务以及相关技术
前后端分离开发。前端项目分为admin-vue(工作人员使用的后台管理系统)、shop-vue(面向公众访问的web网站)、app(公众)、小程序(公众)

  • 商品服务:商品的增删改查、商品的上下架、商品详情
  • 支付服务
  • 优惠服务
  • 用户服务:用户的个人中心、收获地址
  • 仓储服务:商品的库存
  • 秒杀服务
  • 订单服务:订单增删改查
  • 检索服务:商品的检索ES
  • 中央认证服务:登陆、注册、单点登录、社交登录
  • 购物车服务:
  • 后台管理系统:添加优惠信息等

三、linux环境搭建

1、安装&配置linux虚拟机

(1)安装linux

linux虚拟机可以使用VMWare,但推荐安装vitualbox,它是开源的。

  • 下载:https://www.virtualbox.org
  • 安装:需要cpu开启虚拟化,在开机启动的时候设置:cpu configuration—>Intel Vitualization Technology,重启电脑后,再安装
    在这里插入图片描述在这里插入图片描述
    普通安装linux虚拟机太麻烦,我们可以利用vagrant快速创建一个虚拟机,vagrant有一个镜像仓库,里面有好多做好的镜像,比如centos,我们只需要用vagrant连接vitualbox快速的从镜像仓库中创建一个虚拟机
  • 下载:https://www.vagrantup.com/downloads
  • 安装:傻瓜式安装,安装完成后重启电脑,cmd中输入vagrant有vagrant的命令提示代表安装成功
  • 创建虚拟机:在cmd输入vagrant init centos/7,即可初始化一个centos7(注意这个命令在哪个目录下执行的,他的Vagrantfile就生成在哪里)
    补充:初始化的版本可以从vagrant镜像仓库查看
  • 启动虚拟机:vagrant up,启动成功出现default: Rsyncing folder: /Users/wangyang/ => /vagrant。然后ctrl+c退出
  • 连接虚拟机:vagrant ssh,使用exit退出

下次使用可以直接vagrant up直接启动,但要确保当前文件夹下有一个Vagrantfile,不过我们也可以配置环境变量。
启动成功后使用vagrant ssh连接上即可

(2)虚拟网络设置

虚拟机默认的网络使用的是网络地址转换NAT(端口转发)

使用端口转发的方式,若想要访问linux的mysql,需要在vituralbox里设置本机windows的端口比如3333与linux的3306端口绑定,并且每次在linux装一个软件都需要做一个端口映射。我们希望给虚拟机一个固定的ip地址,windows可以和虚拟机互相ping通,虚拟机里面装好一个软件,我们就拿ip地址访问就可以了。有两种方式:

  • 在虚拟机中改网卡的信息,这样比较麻烦
  • vagrant默认使用用户文件下的vagrantFile这个文件帮我们创建出虚拟机信息的,这个文件里有关于网络的一些配置。修改其中的config.vm.network "private_network",ip:"192.168.56.10",这个ip需要在windows的ipconfig中查到vitualbox的虚拟网卡ip,然后更改下最后一个数字就行(不能是1,1是我们的主机)。配置完后vagrant reload重启虚拟机。在虚拟机中ip addr就可以查看到地址了(eth1的ip)。互相ping也能ping通。

2、安装docker

docker是虚拟化容器技术,基于镜像,可以秒级启动各种容器,每个容器都是一个完整的运行环境,容器之间互相隔离
解决的痛点:以前在虚拟机上装软件,比如装mysql、redis需要源码编译、执行运行、开启服务等一大堆步骤,而且某个软件在运行期间如果出现了问题,可能会影响linux系统,linux里面安装的其他环境都会出现问题。
在这里插入图片描述
安装文档:https://docs.docker.com/engine/install/centos/
镜像仓库:dockerHub
安装步骤:

#卸载系统之前的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

# 配置镜像(告诉linux,docker去哪里装)
sudo yum-config-manager \
    --add-repo \
    https://download.docker.com/linux/centos/docker-ce.repo
  
#安装docker的引擎、客户端及容器  
sudo yum install docker-ce docker-ce-cli containerd.io

#启动docker服务
sudo systemctl start docker
# 设置开机自启动
sudo systemctl enable docker

docker常用命令:

#查看docker版本
docker -v
#查看docker镜像
sudo docker images

为docker配置镜像加速:
因为docker下载镜像默认从dockerHub中下载,而dockerHub是一个国外的网站,下载速度比较慢,我们可以配置一个国内的镜像加速,以后docker想要下载镜像就非常快了,镜像加速推荐大家使用阿里云。根据https://cr.console.aliyun.com/cn-qingdao/instances/mirrors执行完命令

#创建一些目录
sudo mkdir -p /etc/docker

#配置镜像加速器地址
sudo tee /etc/docker/daemon.json <<-'EOF'
{
   
  "registry-mirrors": ["https://chqac97z.mirror.aliyuncs.com"]
}
EOF

#重启docker的伴随线程
sudo systemctl daemon-reload

#重启docker服务
sudo systemctl restart docker

3、docker安装mysql

  1. 从docker镜像仓库中搜索并下载mysql,如果不指定版本则下载最新版本
#下载镜像
sudo docker pull mysql:5.7
#检查下载的镜像
sudo docker images
  1. 启动mysql
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

参数说明:
-p:端口映射,将容器的3306端口映射到主机的3306端口
–name:指定容器名字
-v:目录挂载
-e:设置mysql参数(初始化root用户的密码)
-d:后台运行,mysql5.7指的是我们是用哪个镜像启动

su root 密码为vagrant,这样就可以不写sudo了
#查看docker正在运行的进行
[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

此时就可以用客户端连接mysql了
补充知识:
1⃣️、每docker run就会启动一个容器,而且容器跟容器之间是互相隔离的,且每一个容器都是一个完整的运行环境(其实就是一个完整的linux)
如何验证?

#以交互模式进入容器中linux的bash控制台
docker exec -it mysql /bin/bash

ls /
#发现目录结构就是一个完整的linux目录结构,mysql就被装在这个linux里面

#查询mysql在哪里
whereis mysql

#推出交互模式
exit

2⃣️、docker容器端口映射和文件挂载
端口映射: mysql装到了容器里面,mysql默认会有一个端口3306,但这个端口相当于是在mysql容器里用的端口,如果我们想要访问mysql需要把3306映射到linux里面,-p 3306:3306意思就是linux的3306端口与mysql容器内部的3306端口对应,相当于访问linux的3306就能访问到容器内部装的mysql
文件挂载: mysql是被装在容器内部,mysql的配置文件是在/etc/mysql下,mysql的相关日志在/var/log/mysql目录下。但是难道我们每次修改mysql的相关配置都需要进到容器内部来改嘛?太麻烦了,我们希望将我们经常要用到或查看的内容映射到linux的目录里,-v的命令就是这个作用。相当于我们之前做的快捷方式
在这里插入图片描述
3. 修改mysql的配置

#因为有目录映射,所以我们可以直接在linux里修改
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
docker restart mysql

这些配置也会映射到容器内部

4、docker安装redis

  1. 下载镜像文件
docker pull redis
  1. 创建实例并启动
# 如果直接挂载的话docker会以为挂载的是一个目录,所以我们先创建一个文件然后再挂载,在虚拟机中。
# 在虚拟机中
mkdir -p /mydata/redis/conf
touch /mydata/redis/conf/redis.conf

#启动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
  1. 连接redis
docker exec -it redis redis-cli

redis默认是不持久化的。在配置文件中输入appendonly yes,就可以aof持久化了。

vim /mydata/redis/conf/redis.conf
# 插入下面内容
appendonly yes

#重启redis
docker restart redis

设置redis容器在docker启动的时候启动

docker update redis --restart=always

四、开发环境

  1. jdk最低使用1.8版本的
  2. maven在settings中配置阿里云镜像,配置jdk1.8
  3. idea安装插件lombok,mybatisX。idea设置我们的maven
  4. 下载vsCode用于前端管理系统。在vsCode里安装插件:Auto Close Tag、Auto Rename Tag、Chinese、ESlint、HTML CSS Support、HTML Snippets、JavaScript ES6、Live Server、open in brower、Vetur
  5. git相关:
    下载&安装git,右键git bash/gui here,去bash
# 配置用户名
git config --global user.name "username"  //(名字,随意写)

# 配置邮箱
git config --global user.email "222333@qq.com" // 注册账号时使用的邮箱

# 配置ssh免密登录
ssh-keygen -t rsa -C "222333@qq.com"
#三次回车后生成了密钥
#查看密钥
cat ~/.ssh/id_rsa.pub

#需要将密钥复制到码云里面,浏览器登录码云后,个人头像上点设置--ssh公钥
#添加公钥,标题随便写,将查看的id_rsa.pub里的公钥内容复制过来

# 测试
ssh -T git@gitee.com
#测试成功,手动输入yes,就可以无密给码云推送仓库了

五、创建微服务项目

在码云新建仓库,仓库名gulimall,选择语言java,在.gitignore选中maven(就会忽略掉maven一些个人无需上传的配置文件),许可证选Apache-2.0,开发模型选生产/开发模型,开发时在dev分支,发布时在master分支。

在IDEA中New–Project from version control–git–复制刚才项目的地址,如https://github.com/1046762075/mall

IDEA然后New Module–Spring Initializer–group填com.atguigu.gulimall、Artifact填 gulimall-product、describe填谷粒商城商品服务,Next—选择web(web开发)、springcloud routing里选中openFeign(rpc调用)。
依次创建出以下服务:

  • 商品服务product
  • 仓储服务ware
  • 订单服务order
  • 优惠券服务coupon
  • 用户服务member

共同点:

  • 导入web和openFeign
  • group:com.atguigu.gulimall
  • Artifact:gulimall-XXX
  • 每一个服务,包名com.atguigu.gulimall.XXX{product/order/ware/coupon/member}
  • 模块名:gulimall-XXX

然后右下角显示了springboot的service选项,选择
从某个项目粘贴个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>

在maven窗口刷新,并点击+号,找到刚才的pom.xml添加进来,发现多了个root。这样比如运行root的clean命令,其他项目也一起clean了。

修改总项目的.gitignore,把小项目里的垃圾文件在提交的时候忽略掉,比如target

**/mvnw
**/mvnw.cmd
**/.mvn
**/target/
.idea
**/.gitignore

如果你是拉取的我的仓库,你也可以看到我仓库里是没有那些target目录的,非常精简

在git/local Changes,点击刷新看Unversioned Files,可以看到变化。

全选最后剩下21个文件,选择右键、Add to VCS。

在IDEA中安装插件:gitee,重启IDEA。

在Default changelist右键点击commit,去掉右面的勾选Perform code analysis、CHECK TODO,然后点击COMMIT,有个下拉列表,点击commit and push才会提交到云端。此时就可以在浏览器中看到了。

commit只是保存更新到本地
push才是提交到gitee

六、数据库

打开navicat,连接linux里的mysql docker镜像

注意:重启linux和docker,docker里的容器就关了

sudo docker ps
sudo docker ps -a
#这两个命令的区别:后者会显示已创建未启动的容器

#接下来设置我们要用的容器每次都自启
sudo docker update redis --restart=always
sudo docker update mysql --restart=always
#如果不设置上面的自启的话,也可以手动启动
sudo docker start mysql
sudo docker start redis
#如果要进入已启动的容器
sudo docker exec -it mysql /bin/bash
# /bin/bash就是进入一般的命令行,如果改成redis就是进入了redis

使用powerDesigner打开并查看数据库表关系

name是给我们看的,code才是数据库里真正的信息。
选择primary和identity作为主键。然后点preview就可以看到生成这张表的语句。
点击菜单栏database–generate database—点击确定

使用navicat分别创建gulimall-oms、gulimall-pms、gulimall-sms、gulimall-ums、gulimall-wms库,并创建数据库表,sql:https://github.com/FermHan/gulimall。

1、所有的数据库数据再复杂也不建立外键,因为在电商系统中,数据量大,做外间关联很耗性能
2、字符集选utf8mb4,他能兼容utf8且能解决一些乱码的问题。

七、人人开源搭建后台管理系统

在码云上搜索人人开源,我们使用renren-fast(后端)、renren-fast-vue(前端)项目。项目地址:https://gitee.com/renrenio

#克隆代码
git clone https://gitee.com/renrenio/renren-fast.git
git clone https://gitee.com/renrenio/renren-fast-vue.git

下载到桌面,我们把renren-fast移到我们项目文件夹里(删掉.git文件),renren-fast-vue用VSCode打开(后面再弄)

1、使用人人开源搭建后端

在idea的父项目的pom.xml中添加一个renren-fast

<modules>
    <module
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值