一、项目背景
电商模式
市面上有5种常见的电商模式 B2B 、B2C、C2B 、C2C、O2O;
1.B2B模式
B2B(Business to Business) ,是指商家与商家建立的商业关系。如:阿里巴巴
2.B2C模式
B2C(Business to Consumer),就是我们经常看到的供应商直接把商品卖给用户,即“商对客”模式,也就是商业零售,直接面向消费者销售产品和服务。如:苏宁易购,京东,天猫,小米商城等。
3.C2B模式
C2B(Customer to Business),即消费者对企业。先有消费者需求而后有企业生产,即先有消费者提出需求,后有生产企业按需求组织生产。
4.C2C模式
C2C(Customer to Consumer),客户之间自己把东西放上网去卖,如:淘宝,咸鱼
5.O2O模式
O2O即Online To Offline,也即线下商务的机会和互联网结合在了一起,让互联网成为线下交易的前台。线上快速支付,线下优质服务。如:饿了么,美团,淘票票,京东到家
谷粒商城
谷粒商城是一个B2C模式的电商平台,销售自营商品给客户
二、分布式基础概念
1.微服务
微服务架构风格,就像把一个单独的应用程序开发为一套小服务,每个小服务运行在自己的进程中。并使用轻量级机制通信,通常是HTTP API。这些服务围绕业务能力来构建,并通过完全自动化部署机制来独立部署。这些服务使用不同的编程语言书写,以及不同数据存储技术,并保持最低限度的集中式管理。
简而言之:拒绝大型单体应用,基于业务边界进行微服务化拆分,各个服务独立部署运行。
2.集群&分布式&节点
集群是一个物理形态,分布式是一个工作方式。
只要有一堆机器,就可以叫集群。
《分布式系统原理与范型》定义:
分布式系统是若干独立计算机的集合, 这些计算机对用户来说就像单个相关系统。
分布式系统(distributed system)是建立在网络之上的软件系统。
分布式是指将不同的业务放在不同的地方。
集群指的是将几台服务器集中在一起,实现同一业务。
分布式中的每一个节点,都可以做集群。而集群并不一定就是分布式的
节点:集群中的一个服务器
3.远程调用
在分布式系统中,各个服务可能处于不同主机,但是服务之间不可避免的需要互相调用,我们称之为远程调用。
4.负载均衡
分布式系统中,A服务器需要调用B服务,B服务在多台机器中都存在,A调用任意一个服务器均可完成功能。
为了使每一个服务器都不要太忙或者太闲,可以负载均衡的调用每一个服务器,提升网站的健壮性。
常见的负载均衡算法:
**轮询:**为第一个请求选择健康池中的第一台后端服务器,然后按顺序往后依次选择,直到最后一个,然后循环。
**最小连接:**优先选择连接数最少,也就是压力最小的后端服务器,在会话较长的情况下,可以考虑采取这种方式。
**散列:**根据请求源的IP的散列(hash)来选择要转发的服务器。这种方式可以一定程度上保证特定用户能连接到相同的服务器。如果你的应用需要处理状态而要求用户能连接到和之前相同的服务器,可以采取这种方式。
5.服务注册/发现&注册中心
A服务调用B服务,A服务并不知道B服务当前在哪几台机器有,哪些正常的,哪些服务已经下线。解决这个问题可以引入注册中心;
如果某些服务下线,我们其他人可以实时的感知到其他服务的状态,从而避免调用不可用的服务。
6.配置中心
每个服务最终都有大量的配置,并且每个服务都可能部署在多台机器上。我们经常需要变更配置,我们可以让每个服务在配置中心获取自己的配置。
配置中心用来集中管理微服务的配置信息
7.服务熔断&服务降级
在微服务架构中,微服务之间通过网络进行通信,存在相互依赖,当其中一个服务不可用时,可能会造成雪崩效应。要防止这样的情况,必须要有容错机制来保护服务。
1)服务熔断
设置服务的超时,当被调用的服务经常失败达到某个阈值,我们可以开启断路保护机制,后来的请求不再去调用这个服务。本地直接返回默认的数据。
2)服务降级
在运维期间,当系统处于高峰期,系统资源紧张,我们可以让非核心业务降级运行。降级:某些服务不处理,或者简单处理(抛异常、返回NULL、调用Mock数据、调用Fallback处理逻辑)。
8.API网关
在微服务架构中, API Gateway作为整体架构的重要组件,它抽象了微服务中都需要的公共功能,同时提高了客户端负载均衡,服务自动熔断,灰度发布,统一认证,限流控制,日志统计等丰富功能,帮助我们解决很多API管理难题。
三、项目架构图
项目微服务架构图
微服务划分图
四、环境
我这里使用的是阿里云服务器
1.Linux系统
2.安装Docker
Docker基于镜像,可以秒级启动各种容器。每种容器都是一个完整的运行环境,容器之间相隔离。
官方地址:Install Docker Engine on CentOS | Docker Documentation
#1.卸载旧的版本
yum remove docker \
docker-client \
docker-client-latest \
docker-common \
docker-latest \
docker-latest-logrotate \
docker-logrotate \
docker-engine
# 2.需要的安装包
yum install -y yum-utils
# 3.设置镜像的仓库
yum-config-manager \
--add-repo \
https://download.docker.com/linux/centos/docker-ce.repo
# 建议安装阿里云
yum-config-manager \
--add-repo \
http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
#4更新yum软件包索引
yum makecache fast
# 5安装docker相关的内容 docker-ce 社区 ee企业版
yum install docker-ce docker-ce-cli containerd.io
#6 启动docker
systemctl start docker
#7.使用 docker version 查看是否安装成功
#8. systemctl enable docker 开机自启
#9镜像加速
sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<-'EOF'
{
"registry-mirrors": ["https://g6yrjrwf.mirror.aliyuncs.com"]
}
EOF
sudo systemctl daemon-reload
sudo systemctl restart docker
3.Docker 安装mysql
# docker pull mysql 是下载最新版本
#docker pull mysql:版本号 是下载指定版本
[root@stor01 ~]# docker pull mysql:8.0.23
删除镜像操作:
# docker rmi -f 镜像id #删除指定的镜像
# docker rmi -f 镜像id 容器id 容器id #删除多个镜像id
# docker rmi -f $(docker images -aq) # 删除全部镜像
创建实例并启动
# --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:8.0.23
上面的设置有错 可以改为以下内容:
docker run -d -p 3306:3306 -v /home/mysql/log:/var/log/mysql -v /home/mysql/conf:/etc/mysql/conf.d -v /home/mysql/data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 --name mysql mysql:8.0.23
参数说明:
-p 3306:3306 :将容器3306端口映射到主机的3306端口
--name :起名
-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 :初始化root用户的密码
-d mysql:8.0.23 #以后台方式运行
出现的错误
docker: Error response from daemon: driver failed programming external connectivity on endpoint mysql (b18bb8f67f91d02d1498115f6aebf9dbee8c5edf7d6bb39021b7e7807a5c2116): Error starting userland proxy: listen tcp4 0.0.0.0:3306: bind: address already in use.
解决办法:
[root@stor01 ~]# netstat -tanlp 查看当前占用端口命令
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp6 0 0 :::33060 :::* LISTEN 1975/mysqld
tcp6 0 0 :::3306 :::* LISTEN 1975/mysqld
tcp6 0 0 :::26379 :::* LISTEN 20898/redis-sentine
tcp6 0 0 :::111 :::* LISTEN 32590/rpcbind
tcp6 0 0 :::20048 :::* LISTEN 32598/rpc.mountd
tcp6 0 0 :::40625 :::* LISTEN 32588/rpc.statd
#杀死进程(注意不是杀死端口,而是pid的端口)
[root@stor01 ~]# kill 1975
出现的错误
原因是:之前运行的docker容器还没有退出,导致揣想那容器重名情况
[root@stor01 ~]# 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:8.0.23
docker: Error response from daemon: Conflict. The container name "/mysql" is already in use by container "4f7982a05d32acb2563f79f83d8be858e5652b9daa11a6b118d1f954cd15dc35". You have to remove (or rename) that container to be able to reuse that name.
See 'docker run --help'.
解决办法
[root@stor01 ~]# docker ps -a # 查看所有运行的容器
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
4f7982a05d32 mysql:8.0.23 "docker-entrypoint.s…" 12 minutes ago Created mysql
57599ed1ba88 fa989ba2cbe1 "java -jar /app.jar …" 2 weeks ago Exited (143) 4 days ago kuangapp_kuangapp_1
686d572dfbfa efb4fa30f1cf "docker-entrypoint.s…" 2 weeks ago Exited (0) 4 days ago kuangapp_redis_1
76d02308eabb 7149d6fde740 "flask run" 2 weeks ago Exited (137) 2 weeks ago composetest_web_1
e05f32db1027 efb4fa30f1cf "docker-entrypoint.s…" 2 weeks ago Exited (0) 2 weeks ago composetest_redis_1
fa0487332774 d1165f221234 "/hello" 2 weeks ago Exited (0) 2 weeks ago cool_wu
#解决办法:删除重名的容器
[root@stor01 ~]# docker rm 4f7982a05d32
4f7982a05d32
[root@stor01 ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
57599ed1ba88 fa989ba2cbe1 "java -jar /app.jar …" 2 weeks ago Exited (143) 4 days ago kuangapp_kuangapp_1
686d572dfbfa efb4fa30f1cf "docker-entrypoint.s…" 2 weeks ago Exited (0) 4 days ago kuangapp_redis_1
76d02308eabb 7149d6fde740 "flask run" 2 weeks ago Exited (137) 2 weeks ago composetest_web_1
e05f32db1027 efb4fa30f1cf "docker-entrypoint.s…" 2 weeks ago Exited (0) 2 weeks ago composetest_redis_1
fa0487332774 d1165f221234 "/hello" 2 weeks ago Exited (0) 2 weeks ago cool_wu
[root@stor01 ~]# 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:8.0.23
ebc4cf9fc283bdb24a188c0df7cd04c5fb14f0ea7d6a5ffe0c0841295ccbacc6
出现的错误# 发现MySQL启动不了
# 发现MySQL启动不了
[root@stor01 ~]# docker exec -it mysql bash
Error response from daemon: Container ebc4cf9fc283bdb24a188c0df7cd04c5fb14f0ea7d6a5ffe0c0841295ccbacc6 is not running
# docker start 容器id 也没有启动成功mysql
[root@stor01 ~]# docker start mysql
mysql
[root@stor01 ~]# docker exec -it mysql bash
Error response from daemon: Container ebc4cf9fc283bdb24a188c0df7cd04c5fb14f0ea7d6a5ffe0c0841295ccbacc6 is not running
#查看日志
[root@stor01 ~]# docker logs mysql
2021-06-16 12:03:27+00:00 [Note] [Entrypoint]: Entrypoint script for MySQL Server 8.0.23-1debian10 started.
2021-06-16 12:03:27+00:00 [Note] [Entrypoint]: Switching to dedicated user 'mysql'
2021-06-16 12:03:27+00:00 [Note] [Entrypoint]: Entrypoint script for MySQL Server 8.0.23-1debian10 started.
2021-06-16 12:03:27+00:00 [Note] [Entrypoint]: Initializing database files
2021-06-16T12:03:27.895952Z 0 [System] [MY-013169] [Server] /usr/sbin/mysqld (mysqld 8.0.23) initializing of server in progress as process 41
2021-06-16T12:03:27.901652Z 1 [System] [MY-013576] [InnoDB] InnoDB initialization has started.
2021-06-16T12:03:29.032258Z 1 [System] [MY-013577] [InnoDB] InnoDB initialization has ended.
2021-06-16T12:03:30.260759Z 6 [Warning] [MY-010453] [Server] root@localhost is created with an empty password ! Please consider switching off the --initialize-insecure option.
2021-06-16 12:03:32+00:00 [Note] [Entrypoint]: Database files initialized
2021-06-16 12:03:32+00:00 [Note] [Entrypoint]: Starting temporary server
mysqld: Error on realpath() on '/var/lib/mysql-files' (Error 2 - No such file or directory)
2021-06-16T12:03:33.124599Z 0 [ERROR] [MY-010095] [Server] Failed to access directory for --secure-file-priv. Please make sure that directory exists and is accessible by MySQL Server. Supplied value : /var/lib/mysql-files
2021-06-16 12:03:33+00:00 [ERROR] [Entrypoint]: Unable to start server.
2021-06-16 13:17:55+00:00 [Note] [Entrypoint]: Entrypoint script for MySQL Server 8.0.23-1debian10 started.
2021-06-16 13:17:55+00:00 [Note] [Entrypoint]: Switching to dedicated user 'mysql'
2021-06-16 13:17:55+00:00 [Note] [Entrypoint]: Entrypoint script for MySQL Server 8.0.23-1debian10 started.
mysqld: Error on realpath() on '/var/lib/mysql-files' (Error 2 - No such file or directory)
2021-06-16T13:17:56.271218Z 0 [ERROR] [MY-010095] [Server] Failed to access directory for --secure-file-priv. Please make sure that directory exists and is accessible by MySQL Server. Supplied value : /var/lib/mysql-files
2021-06-16T13:17:56.271241Z 0 [ERROR] [MY-010119] [Server] Aborting
解决办法
docker run -d -p 3306:3306 -v /home/mysql/log:/var/log/mysql -v /home/mysql/conf:/etc/mysql/conf.d -v /home/mysql/data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 --name mysql mysql:8.0.23
[root@stor01 ~]# docker run -d -p 3306:3306 -v /home/mysql/log:/var/log/mysql -v /home/mysql/conf:/etc/mysql/conf.d -v /home/mysql/data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 --name mysql mysql:8.0.23
950ef303c587ec5a7a86650c79982db713a9ba5003d31b8e24d121ecc569570b
[root@stor01 ~]# docker ps -a # 查看运行的程序
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
950ef303c587 mysql:8.0.23 "docker-entrypoint.s…" 5 minutes ago Up 5 minutes 0.0.0.0:3306->3306/tcp, 33060/tcp mysql
docker 容器文件挂载与端口映射
[root@stor01 ~]# docker exec -it 950ef303c587 /bin/bash #进入这个容器
root@950ef303c587:/# ls /
bin dev entrypoint.sh home lib64 mnt proc run srv tmp var
boot docker-entrypoint-initdb.d etc lib media opt root sbin sys usr
root@950ef303c587:/# whereis mysql
mysql: /usr/bin/mysql /usr/lib/mysql /etc/mysql
root@950ef303c587:/# cd /var/log
root@950ef303c587:/var/log# ls
alternatives.log apt btmp dpkg.log faillog lastlog mysql wtmp
root@950ef303c587:/var/log# cd mysql/
root@950ef303c587:/var/log/mysql# ls
root@950ef303c587:/var/log/mysql# exit
exit
[root@stor01 ~]#
Mysql配置
因为有目录映射,所以我们可以直接在镜像外执行
vi /home/mysql/conf/my.cnf
[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
[root@stor01 ~]# cd /home
[root@stor01 home]# ls
apache-tomcat-9.0.44-windows-x64 dockerfile jdk-8u291-linux-x64.tar.gz my_wordpress test
apache-tomcat-9.0.45 Dockerfile kuangapp qinjiang tomcatlogs
apache-tomcat-9.0.45.tar.gz docker-test-volume kuangshen readme.txt www
ceshi idea kuangshen.java redis
composetest jdk-8u291-linux-x64.rpm mysql swagger-demo-0.0.1-SNAPSHOT.jar
[root@stor01 home]# cd mysql/
[root@stor01 mysql]# ls
conf data log
[root@stor01 mysql]# cd conf/
[root@stor01 conf]# ls
[root@stor01 conf]# vi my.cnf
[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
[root@stor01 conf]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
950ef303c587 mysql:8.0.23 "docker-entrypoint.s…" 31 minutes ago Up 31 minutes 0.0.0.0:3306->3306/tcp, 33060/tcp mysql
[root@stor01 conf]# docker restart mysql
mysql
[root@stor01 conf]# docker exec -it mysql /bin/bash
root@950ef303c587:/# cd /etc/mysql
root@950ef303c587:/etc/mysql# ls
conf.d my.cnf my.cnf.fallback
root@950ef303c587:/etc/mysql# cat my.cnf
# Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; version 2 of the License.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#
# The MySQL Server configuration file.
#
# For explanations see
# http://dev.mysql.com/doc/mysql/en/server-system-variables.html
[mysqld]
pid-file = /var/run/mysqld/mysqld.pid
socket = /var/run/mysqld/mysqld.sock
datadir = /var/lib/mysql
secure-file-priv= NULL
# Custom config should go here
!includedir /etc/mysql/conf.d/
root@950ef303c587:/etc/mysql# cd ..
root@950ef303c587:/etc# cd ..
root@950ef303c587:/# cd /etc/mysql/conf.d
root@950ef303c587:/etc/mysql/conf.d# ls
my.cnf
root@950ef303c587:/etc/mysql/conf.d# cat my.cnf
[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
root@950ef303c587:/etc/mysql/conf.d#