谷粒商城 -->「P01-P44」

在这里插入图片描述

文章目录

分布式基础篇

1.项目简介

1.1项目背景

市面上有5种常见的电商模式 B2B、B2C、C2B、C2C、O2O

1.2电商模式

1.2.1 B2B 模式
B2B(Business to Business),是指商家和商家建立的商业关系,如阿里巴巴
1.2.2 B2C 模式
B2C(Business to Consumer) 就是我们经常看到的供应商直接把商品卖给用户,
即 “商对客” 模式,也就是我们呢说的商业零售,直接面向消费销售产品和服务,
如苏宁易购,京东,天猫,小米商城
1.2.1 C2B 模式
C2B (Customer to Business),即消费者对企业,先有消费者需求产生
而后有企业生产,即先有消费者提出需求,后又生产企业按需求组织生产
1.2.1 C2C 模式
C2C (Customer to Consumer) 客户之间把自己的东西放到网上去卖 。
如淘宝、咸鱼
1.2.1 O2O 模式
O2O 即 Online To Offline,也即将线下商务的机会与互联网
结合在一起,让互联网成为线上交易前台,线上快速支付,线上优质服务,
如:饿了么,美团,淘票票,京东到家

1.3谷粒商城

谷粒商城是一个B2C模式的电商平台,销售自营商品给客户

1.4项目架构图

csdn机制问题导致图片丢失,可以查看本人的个人博客:谷粒商城-P01-P44

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-mUQdvdIc-1651150085131)(https://cdn.jsdelivr.net/gh/Jonny-Chi/picgo_imgs/BLog/202203312050401.png)]

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

到达服务器后进行处理(springboot为微服务),服务与服务可能会相互
调用(使用feign组件),有些请求可能经过登录才能进行(基于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容器的方式运行。

1.4微服务划分图

image-20220331205307764

反映了需要创建的微服务以及相关技术。

前后分离开发。前端项目分为admin-vue(工作人员使用的后台管理系统)、
shop-vue(面向公众访问的web网站)、app(公众)、小程序(公众)

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

1.5 项目技术&特色

前后分离开发,并开发基于vue的后台管理系统
SpringCloud全新的解决方案
应用监控、限流、网关、熔断降级等分布式方案,全方位涉及
透彻讲解分布式事务,分布式锁等分布式系统的难点
压力测试与性能优化
各种集群技术的区别以及使用
CI/CD 使用

1.6项目前置要求

熟悉SpringBoot以及常见整合方案
了解SpringCloud
熟悉 git  maven
熟悉 linux redis docker 基本操作
了解 html,css,js,vue
熟练使用idea开发项目
1.6.1 学习项目的前置知识
熟悉SpringBoot以及常见整合方案
了解SpringCloud
熟悉 git  maven
熟悉 linux redis docker 基本操作
了解 html,css,js,vue
熟练使用idea开发项目

2.分布式基础概念

2.1 微服务

微服务架构风格,就像是把一个单独的应用程序开发成一套小服务,每个小
服务运行在自己的进程中,并使用轻量级机制通信,通常是 HTTP API 这些
服务围绕业务能力来构建,	并通过完全自动化部署机制来独立部署,这些服
务使用不同的编程语言书写,以及不同数据存储技术,并保持最低限度的集中式管理

简而言之,拒绝大型单体应用,基于业务边界进行服务微化拆分,每个服务独
立部署运行。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-SXbVYLUu-1651150085132)(https://cdn.jsdelivr.net/gh/Jonny-Chi/picgo_imgs/BLog/202203312127361.png)]

2.2 集群&分布式&节点

集群是个物理状态,分布式是个工作方式

只要是一堆机器,也可以叫做集群,他们是不是一起协作干活,
这谁也不知道。

《分布式系统原理与范型》定义:

分布式系统是若干独立计算机的集合,这些计算机对于用户来说像单个系统
分布式系统 (distributed system) 是建立网络之上的软件系统

分布式是指根据不同的业务分布在不同的地方

集群指的是将几台服务器集中在一起,实现同一业务

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

分布式中的每一个节点,都可以做集群,而集群并不一定就是分布式的

节点:集群中的一个服务器

2.3 远程调用

在分布式系统中,各个服务可能处于不同主机,但是服务之间不可避免的需要
互相调用,我们称之为远程调用

SpringCloud中使用HTTP+JSON的方式来完成远程调用

image-20220331212822366

2.4 负载均衡

image-20220331213041212

分布式系统中,A 服务需要调用B服务,B服务在多台机器中都存在, 
A调用任意一个服务器均可完成功能

为了使每一个服务器都不要太或者太闲,我们可以负载均衡调用每一个服务器,
提升网站的健壮性

常见的负载均衡算法:
轮询:为第一个请求选择健康池中的每一个后端服务器,然后按顺序往后依
次选择,直到最后一个,然后循环

最小连接:优先选择链接数最少,也就是压力最小的后端服务器,在会话较
长的情况下可以考虑采取这种方式

2.5 服务注册/发现&注册中心

A服务调用B服务,A服务不知道B服务当前在哪几台服务器上有,哪些正常
的,哪些服务已经下线,解决这个问题可以引入注册中心

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0krXGJL2-1651150085133)(https://cdn.jsdelivr.net/gh/Jonny-Chi/picgo_imgs/BLog/202203312132193.png)]

如果某些服务下线,我们其他人可以实时的感知到其他服务的状态,
从而避免调用不可用的服务

2.6 配置中心

image-20220331213348013

每一个服务最终都有大量配置,并且每个服务都可能部署在多个服务
器上,我们经常需要变更配置,我们可以让每个服务在配置中心获取
自己的配置。

配置中心用来集中管理微服务的配置信息

2.7 服务熔断&服务降级

在微服务架构中,微服务之间通过网络来进行通信,存在相互依赖,
当其中一个服务不可用时,有可能会造成雪崩效应,要防止这种情
况,必须要有容错机制来保护服务

image-20220331213538251

rpc
情景:
订单服务 --> 商品服务 --> 库存服务

库存服务出现故障导致响应慢,导致商品服务需要等待,可能等到10s后库存服
务才能响应。库存服务的不可用导致商品服务阻塞,商品服务等的期间,订单服
务也处于阻塞。一个服务不可用导致整个服务链都阻塞。如果是高并发,第一个
请求调用后阻塞10s得不到结果,第二个请求直接阻塞10s。更多的请求进来导致
请求积压,全部阻塞,最终服务器的资源耗尽。导致雪崩

1、服务熔断
设置服务的超时,当被调用的服务经常失败到达某个阈值,我们可以开启断路保
护机制,后来的请求不再去调用这个服务,本地直接返回默认的数据

2、服务降级
在运维期间,当系统处于高峰期,系统资源紧张,我们可以让非核心业务降级
运行,降级:某些服务不处理,或者简单处理【抛异常,返回NULL,调用 
Mock数据,调用 FallBack 处理逻辑】

2.8 API 网关

在微服务架构中,API Gateway 作为整体架构的重要组件,抽象服务中
需要的公共功能,同时它提供了客户端负载均衡,服务自动熔断,灰度发布,统
一认证,限流监控,日志统计等丰富功能,帮助我们解决很多API管理的难题

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-zTgPD88G-1651150085134)(https://cdn.jsdelivr.net/gh/Jonny-Chi/picgo_imgs/BLog/202203312137369.png)]

3 环境搭建

安装下面这些软件之前建议设置一下Linux的时间

// 查看当前时间
date
// 安装ntpdate
yum install -y ntpdate
// 更新时间
ntpdate 0.asia.pool.ntp.org
// 将系统时间同步到硬件,防止系统重启后时间被还原
hwclock --systohc

// 设置定时任务自动更新时间(每5分钟执行一次)
echo "* 5 * * * /usr/sbin/ntpdate ntp.api.bz > /dev/null 2>&1" >> /var/spool/cron/root

//查看当前Linux有哪些定时任务
crontab -l

//重启定时任务服务
systemctl restart crond.service

3.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 device-mapper-persistent-data lvm2

3  添加软件源信息
sudo yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo

4  更新 yum 缓存
sudo yum makecache fast

5	 安装DOCKER引擎
sudo yum install docker-ce docker-ce-cli containerd.io

6  启动 Docker 后台服务
sudo systemctl start docker
// 设置开机自启
sudo systemctl enable docker

7. Docker配置国内镜像源

vi /etc/docker/daemon.json

添加以下配置
{
   
  "registry-mirrors": [
    "https://registry.docker-cn.com",
    "http://hub-mirror.c.163.com",
    "https://docker.mirrors.ustc.edu.cn"
  ]
}

重新加载配置
sudo systemctl daemon-reload
重新启动docker
sudo systemctl restart docker


3.1.2其他指令(可以不执行的指令)
// 停止
sudo systemctl stop docker
// 重启
sudo systemctl restart docker
// 查看状态
sudo systemctl status docker
// 设置开机自启
sudo systemctl enable docker
// 取消开机自启
sudo systemctl disable docker
// 查看是否已经配置开机自启
sudo systemctl is-enabled docker
3.1.3Docker镜像操作
  • 查看镜像

    sudo docker images
    
  • 拉取镜像
    docker pull 镜像名称:版本号 如:

    sudo docker pull redis:5.0.4
    
  • 删除镜像

    sudo docker rmi 镜像ID
    
  • 运行镜像

    sudo docker run --name test -p 80:80 -p 8081:8081 -v /data/log:/data/log --restart=always -d test:1.0.0
    
    • name
      表示运行的容器的别名

    • p
      宿主机的端口域容器端口的映射关系

    • v

      文件挂载

      • 时间同步

        -v /etc/localtime:/etc/localtime
        
    • restart
      重启方式,自动重启

    • d
      后台运行

  • 镜像打标签
    sudo docker tag 基础镜像:版本 镜像地址(默认docker仓库)/路径/镜像名称:版本 如:

    sudo docker tag redis:5.0.4 hub.c.163.com/test/redis:5.0.4
    
  • 推送镜像

    sudo docker push hub.c.163.com/test/redis:5.0.4
    
3.1.4Docker容器操作
  • 查看容器运行情况

    sudo docker ps
    
  • 查看所有的容器运行情况

    sudo docker ps -a
    
  • 查询特定的容器

    sudo docker ps|grep redis
    
  • 停止容器

    sudo docker stop 容器id
    
  • 重启容器

    sudo docker restart 容器id
    
  • 启动容器

    sudo docker start 容器id
    
  • 删除容器

    sudo docker rm 容器id
    
  • 查看容器运行的日志

    sudo docker logs -f 容器ID
    
    • Docker运行日志保存的目录

      cd /var/lib/docker/containers
      
    • 清理Docker容器运行的日志

      #首先进入上面的目录
      #cd进入对应的容器
      #清空  容器id-json.log的记录文件即可清理容器运行的日志
      #或者停止、删除、重启镜像
      
  • 进入容器

    sudo docker exec -it 容器ID /bin/bash
    

    使用exit退出

  • 执行容器内的脚本
    以Nginx检查配置文件是否正确测试

    sudo docker exec 容器ID /usr/sbin/nginx -s reload
    
3.1.5Docker-compose安装
  • 方式一(推荐)

    // 直接下载
    //   github的源
    sudo curl -L https://github.com/docker/compose/releases/download/1.25.0/docker-compose-`uname -s`-`uname -m` -o /usr/local/bin/docker-compose
    //    Daocloud镜像
    curl -L https://get.daocloud.io/docker/compose/releases/download/1.25.0/docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-compose
    // 下载完成之后设置权限
    sudo chmod +x /usr/local/bin/docker-compose
    // 卸载
    sudo rm /usr/local/bin/docker-compose
    

    file

  • 方式二

    #依赖python 可能受python版本的影响导致安装失败
    yum install epel-release
    yum install -y python-pip
    pip install docker-compose
    
  • 基础命令

    #启动容器,如果镜像不存在则先下载镜像,如果容器没创建则创建容器,如果容器没启动则启动
    docker-compose up -d 
    #停止并移除容器
    docker-compose down 
    #重启服务
    docker-compose restart 
    
  • 异常情况

    Could not find a version that satisfies the requirement requests<3,>=2.20.0 (from docker-compose) (from versions: )
    No matching distribution found for requests<3,>=2.20.0 (from docker-compose)
    You are using pip version 8.1.2, however version 19.3.1 is available.
    You should consider upgrading via the 'pip install --upgrade pip' command.
    

    file

    pip install --upgrade pip
    // 升级成功即可安装
    

    file

3.1.6容器日志管理
  • 容器的日志查看

    sudo docker logs -f 容器ID
    
  • 容器日志保存的位置

    /var/lib/docker/containers/
    

    以上路径下保存了当前容器的各种资源及配置,让容器被删除的时候,这里对应的文件夹也会被删除
    img
    以下红色部分即为容器运行时的日志
    img

  • 带来的问题
    当容器不删除重启的时候,这里的日志文件将会变得越来越大,占用了大量的内存资源;而实际的情况下,以SpringBoot项目为例,我们都会在项目里面定义自己的日志策略,因此容器运行时记录的运行日志实际上是一份多余的日志;既然是日志,必定就会占用IO,IO又是一个比较耗时的操作,而且文件越大,操作的性能就会下降。既然没啥用,那我们何不关掉它。

关闭容器运行日志
  • 配置daemon.json

    vim /etc/docker/daemon.json
    
    #添加以下配置
    "log-driver":"none"
    

    img

    #重启docker
    service docker restart
    

    移除并重新运行镜像,再来查看容器日志,发现*-json.log已经没有了
    个人的建议是,测试环境是可以开启这个容器日志,如果镜像测试一旦稳定,推到生产的时候,出于性能考虑(因为这部分日志没有太大的价值),所以可以直接关闭掉;

限制容器运行日志大小
  • 配置daemon.json

    vim /etc/docker/daemon.json
    
    #添加以下配置
    "log-driver":"json-file",
    "log-opts": {
         "max-size":"1m", "max-file":"3"}
    
    • max-size
      表示日志文件的大小
    • max-file
      表示日志文件的个数,这里是3,那么最多会生成三个日志文件,每个日志文件最大1m;超过3个之后,会把最旧的那个文件给删除掉。imgimg
定时任务清空日志

不太建议使用这种方式,虽然可以解决问题,但是我认为不是一个最好的方法

  • 创建清除日志的脚本
    vim /etc/docker/clean_docker_container_logs.sh

    #!/bin/sh 
    
    echo "======== start clean docker containers logs ========"  
    #查找/var/lib/docker/containers/路径下以-json.log结尾的文件
    logs=$(find /var/lib/docker/containers/ -name *-json.log)  
    for log in $logs  
            do  
                    echo "clean logs : $log"  
                    #将对应文件的内容置为null
                    cat /dev/null > $log  
                    # 或者
                    # echo "">$log
            done  
    echo "======== end clean docker containers logs ========" 
    

    然后在crontab设置定时任务执行

    #5分钟执行一次
    */5 * * * * sh /etc/docker/clean_docker_container_logs.sh
    

3.2 安装mysql

1 拉去mysql镜像
sudo docker pull mysql:5.7

2 启动mysql容器
# --name指定容器名字 -v目录挂载 -p指定端口映射  -e设置mysql参数 -d后台运行
sudo docker run --name mysql -v /opt/docker/mysql/data:/var/lib/mysql -v /opt/docker/mysql/config:/etc/mysql -v /opt/docker/mysql/log:/var/log/mysql  -e MYSQL_ROOT_PASSWORD=root  -p 3306:3306 -d mysql:5.7

3 使用sudo su - root(切换为root,这样就不用每次都sudo来赐予了)
sudo su - root
4 进入mysql容器
docker exec -it 容器名称|容器id bin/bash

3.3安装redis

#1 在docker hub搜索redis镜像
docker search redis

#2 拉取redis镜像到本地
docker pull redis:6.0.10

#3 修改需要自定义的配置(docker-redis默认没有配置文件,
自己在宿主机建立后挂载映射)
#创建并修改/opt/docker/redis/conf/redis.conf
mkdir -p /opt/docker/redis/conf
vi /opt/docker/redis/conf/redis.conf

bind 0.0.0.0 开启远程权限(暂时可以不配置)
appendonly yes 开启aof持久化

#4 启动redis服务运行容器
docker run -p 6379:6379 --name redis -v /opt/docker/redis/data:/data  -v /opt/docker/redis/conf/redis.conf:/etc/redis/redis.conf -d redis redis-server /etc/redis/redis.conf 

解释:-v /opt/docker/redis/data:/data # 将数据目录挂在到本地保证数据安全
-v /opt/docker/redis/conf/redis.conf:/etc/redis/redis.conf   # 将配置文件挂在到本地修改方便
 
#5  直接进去redis客户端。
docker exec -it redis redis-cli

3.4Maven配置(本机)

<!-- 在maven配置文件配置 -->
<!-- 配置阿里云镜像 -->
<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>

<!-- 配置 jdk 1.8 编译项目 -->
<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>

3.5安装开发插件(本机)(可选-方便开发)

vscode

Auto Close Tag  
Auto Rename Tag 
Chinese 
ESlint 
HTML CSS Support
HTML Snippets
JavaScript (ES6) code snippets
Live Server
open in brower
Vetur

idea
lombok、mybatisx

3.6安装git(本机)

3.6.1参考

进行具体配置之前,建议对git不太了解的朋友参考下面内容

查看git相关配置

查看配置 :git config -l

查看系统配置:git config --system --list #配置文件所在路径在Git安装目录下的 Git目录下的etc目录的gitconfig

查看当前用户配置:git config --global --list

#配置文件路径:Windows:C:\User\Adminidtrator\.gitconfig Mac:/Users/用户/.gitconfig

设置用户名与邮箱

  1. 通过命令方式修改用户及邮箱
  • 查看是否已经设置过,用户名及邮箱

  • git config user.name
    git config user.email
    
  • 若已设置,执行下面命令,重设

    • git config --global --unset user.name
      git config --global --unset user.email
      
  • 重置后,重新设置用户名及密码

    • git config --global user.name "xxx" // 配置全局用户名,如Github上注册的用户名
      git config --global user.email "[email protected]" // 配置全局邮箱,如Github上配置的邮箱
      
  1. 通过配置文件直接修改用户和邮箱
  • 打开上面提到的.gitconfig文件,直接添加user和email即可
  • 例图:
  • image-20220331234410801
  1. 对每个账户生成一对密钥
  • 首先进入保存秘钥的目录:

  • cd ~/.ssh // 进入目录,该目录下保存生成的秘钥

  • 然后,根据账户邮箱生成秘钥。例如我在GitHub上的邮箱是******.**.**,则命令为:

  • ssh-keygen -t rsa -C "******.**.**"

  • 输入完成后,会有如下提示:

  • Generating public/private rsa key pair.
    Enter file in which to save the key (/Users/jonny/.ssh/id_rsa):
    

    这里要求对秘钥进行命名,默认的文件名是id_rsa。为了方便区分,我这里命名为id_rsa_github。接下来的提示都直接进行回车,直到秘钥生成。通过ls命令,可以看到刚刚生成的密钥对id_rsa_githubid_rsa_github.pub。其中id_rsa_github.pub是公钥。

    同样,对于GitLab上的账户,我是用另一个邮箱注册的,按照同样的步骤生成id_rsa_gitlab的秘钥对。接下来的步骤,除额外说明外,两个账户的操作完全相同

  • 查看生成的密钥

  • cat id_rsa_gitee.pub 这里的id_rsa_gitee是我上面自定义的文件名,这里可根据自己设置的文件名修改

  1. 私钥添加到本地
  • SSH协议的原理,就是在托管网站上使用公钥,在本地使用私钥,这样本地仓库就可以和远程仓库进行通信。在上一步已经生成了秘钥文件,接下来需要使用秘钥文件,首先是在本地使用秘钥文件:

  • ssh-add ~/.ssh/id_rsa_github // 将GitHub私钥添加到本地 ssh-add ~/.ssh/id_rsa_gitlab // 将GitLab私钥添加到本地

  • 为了检验本地是否添加成功,可以使用ssh-add -l命令进行查看

  1. 对本地秘钥进行配置

由于添加了多个密钥文件,所以需要对这多个密钥进行管理。在.ssh目录下新建一个config文件:

touch config

文件中的内容如下:

Host github // 网站的别名,随意取
HostName github.com // 托管网站的域名
User Jonny // 托管网站上的用户名
IdentityFile ~/.ssh/id_rsa_github // 使用的密钥文件

// Gitee的配置相同
Host gitee
HostName gitee.com
User Jonny
IdentityFile ~/.ssh/id_rsa_gitee

注意,实际写到配置文件中时,一定不要写//的注释,建议直接不写注释

  1. 公钥添加到托管网站

以GitHub为例,先在本地复制公钥。进入.ssh目录,使用vim id_rsa_github.pub查看生成的GitHub公钥,全选进行复制。

登录GitHub,点击右上角头像选择settings,在打开的页面中选择SSH and GPG keys

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-GGAPoe7h-1651150085137)(https://cdn.jsdelivr.net/gh/Jonny-Chi/picgo_imgs/BLog/202204010029377.png)]

在打开的页面的Key输入框中粘贴刚刚复制的公钥,title的名字自己随便去,然后点击下方的Add SSH key按钮:

preview

至此,托管网站的公钥添加完成。总结来说,就是针对每个托管网站分别生成一对密钥,然后分别添加到本地和托管网站。

这时候,可以测试一下配置是否成功,测试命令使用别名。例如,对于GitHub,本来应该使用的测试命令是:

ssh -T [email protected]

在config文件中,给GitHub网站配置的别名就是github,所以直接使用别名,就是

ssh -T git@github

3.6.2如何使用

使用有两种情况,一种情况是从远端拉取代码到本地,一种是本地已有仓库需要与远程仓库关联。

3.6.1.1如果是从远端拉取代码

选择SSH协议的复制命令,如对于GitLab上代码库test,其复制命令为

git clone [email protected]:****/test.git

由于使用了别名gitlab,所以实际使用的复制命令应当为:

git clone git@gitlab:****/test.git

github同理

这种方法较为简单,修改后的代码无需额外配置,可以直接push

3.6.1.2 如果是本地已有的仓库

这种情况适用于本地新建的仓库需要与远端进行关联,或者之前已经使用sourceTree等图形界面软件拷贝的仓库。进入本地仓库文件夹,需要单独配置该仓库的用户名和邮箱

git config user.name "Jonny" git config user.email "******.**.**"

然后,进入本地仓库的git目录,打开config文件

cd .git // 该目录是隐藏的,ls命令不可见,但是可以直接进入,如果是新建的文件夹需要先执行git init vim config

在config文件中,修改(config文件中已有remote "origin"信息)或者添加(config文件中不包含remote "origin"信息)分支信息:

[remote "origin"] url = git@gitlab:GuiLiu/test.git fetch = +refs/heads/*:refs/remotes/origin/*

主要是URL部分,原生的信息一般是[email protected]:GuiLiu/test.git,需要将gitlab.com使用别名gitlab代替。

可以看到,仓库中的关键是要配置好用户名和邮箱,以及使用别名。使用别名的目的是为了通过别名,将本地仓库与密钥目录.ssh文件夹下的密钥进行管理,这样就完成了本地仓库使用的私钥与托管网站使用的公钥的配对,而用户名和邮箱是该仓库使用SSH协议时需要用到的信息

3.6.1.3补充一下Coding

在关联coding上托管的代码时,遇到了一点麻烦,主要是因为别名的修改不正确,以及20端口禁用的问题导致的,所以单独记录下,.ssh目录下的config文件中的密钥信息应该为:

Host coding
HostName git-ssh.coding.net // 这个域名使用coding官网获取的,不能写coding.net
User liugui
IdentityFile ~/.ssh/id_rsa_coding
Port 443 // 20端口可能被禁用,需要使用443端口

注意,实际写到配置文件中时,一定不要写//的注释,建议直接不写注释

3.6.3 谷粒商城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]

# 测试成功
Hi unique_perfect! You've successfully authenticated, but GITEE.COM does not provide shell access.

3.7创建仓库

在码云新建仓库,仓库名gulimall,选择语言java,在.gitignore选中maven,
许可证选Apache-2.0,开发模型选生产/开发模型,开发时在dev分支,
发布时在master分支,创建如图所示

image-20220401005209434

3.8新建项目并创建出以下服务模块

在IDEA中New Project from version control Git  复制刚才项目的地址,如https://gitee.com/***/gulimall.git

创建以下模块
商品服务product
存储服务ware
订单服务order
优惠券服务coupon
用户服务member
每个模块导入web和openFeign

如下图所示

image-20220401094914200

按照上图的格式创建即可

创建父模块:在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>

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

image-20220401111338164


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


3.9创建数据库

#创建数据库之前需要启动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
接着创建数据库
然后接着去sqlyog直接我们的操作,在左侧root上右键建立数据库:
字符集选utf8mb4,他能兼容utf8且能解决一些乱码的问题。分别
建立了下面数据库

gulimall_oms
gulimall_pms
gulimall_sms
gulimall_ums
gulimall_wms

所有的数据库数据再复杂也不建立外键,因为在电商系统里,数据量大,
做外键关联很耗性能。

具体SQL在代码中有,不一一列举出来了

3.10VSCode准备

//在码云上搜索人人开源,我们使用renren-fast,renren-fast-vue项目。
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打开的(后面再弄)
3.10.1renren-fast
idea(root)项目里的pom.xml添加一个
<modules>
    <module>gulimall-coupon</module>
    <module>gulimall-member</module>
    <module>gulimall-order</module>
    <module>gulimall-product</module>
    <module>gulimall-ware</module>

    <module>renren-fast</module>
</modules>

然后打开renren-fast/db/mysql.sql,复制全部,在数据库工具直接执行即可
3.10.2renren-fast-vue
用VSCode打开renren-fast-vue

安装node:
注意:版本为v10.16.3,python版本为3(因为不同版本等下下面遇到的问题可能不一样)【我在这用的是16.14版的】
接下来
npm config set registry http://registry.npm.taobao.org/  # 设置node仓库。提高下载速度

然后在VScode的终端进入项目中输入 npm install,会报错,然后进行如下操作:
报错:
npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! [email protected] install: `node install.js`
npm ERR! Exit status 1
npm ERR!
npm ERR! Failed at the [email protected] install script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.

npm ERR! A complete log of this run can be found in:
npm ERR!     E:\installation_program\nodeRepository\npm_cache\_logs\2021-02-09T07_38_47_075Z-debug.log

解决报错:
npm install chromedriver --chromedriver_cdnurl=http://cdn.npm.taobao.org/dist/chromedriver

报错:
Module build failed: Error: ENOENT: no such file or directory, scandir '/Users/joe/Study/Demo/gulimall/renren-fast-vue/node_modules/node-sass/vendor'

解决报错
1.cd 进入node_modules
$ cd node_modules

2.运行npm rebuild node-sass
$ npm rebuild node-sass

需要等待一段时间:出现 rebuilt dependencies successfully

最后直接运行代码就OK了

浏览器输入localhost:8001 就可以看到内容了,登录账号admin 密码admin

3.11逆向工程搭建

3.11.1product
git clone https://gitee.com/renrenio/renren-generator.git

下载到桌面后,同样把里面的.git文件删除,然后移动到我们IDEA项目目录中,同样配置好pom.xml(root)

<modules>
		<module>gulimall-coupon</module>
		<module>gulimall-member</module>
		<module>gulimall-order</module>
		<module>gulimall-product</module>
		<module>gulimall-ware</module>
		<module>renren-fast</module>
		<module>renren-generator</module>
</modules>
修改renren-generator的application.yml
url: jdbc:mysql://192.168.1.17:3306/gulimall-pms?useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=Asia/Shanghai
username: root
password: root

修改generator.properties
mainPath=com.rabbitboss # 主目录
package=com.rabbitboss.gulimall # 包名
moduleName=product   # 模块名
author=Jonny  # 作者
email=xxx@qq.com  # email
tablePrefix=pms_   # 我们的pms数据库中的表的前缀都有pms,
如果写了表前缀,每一张表对于的javaBean就不会添加前缀了
运行RenrenApplication。如果启动不成功,修改application中是port为80。访问http://localhost:80

然后点击全部,点击生成代码。下载了压缩包

解压压缩包,把main放到gulimall-product的同级目录下。
然后在项目上右击(在项目上右击很重要)new modules— maven—然后在name上输入gulimall-common。

在pom.xml中也自动添加了<module>gulimall-common</module>

在common项目的pom.xml(我们把每个微服务里公共的类和依赖放到common里。)中添加
<!-- 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包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中加入下面内容
<dependency>
    <groupId>com.atguigu.gulimall</groupId>
    <artifactId>gulimall-common</artifactId>
    <version>0.0.1-SNAPSHOT</version>
</dependency>
复制

renren-fast----utils包下的QueryPageUtilsRConstant复制到common项目的java/com.rabbitboss.common.utils下

把@RequiresPermissions这些注解掉,因为是shiro的

复制renren-fast中的xss包粘贴到common的java/com.rabbitboss.common目录下。

还复制了exception文件夹,对应的位置关系自己观察一下就行

注释掉product项目下类中的//import org.apache.shiro.authz.annotation.RequiresPermissions;,他是shiro的东西

注释renren-generator\src\main\resources\template/Controller中所有的
# @RequiresPermissions。
# import org.apache.shiro.authz.annotation.RequiresPermissions;

总之什么报错就去renren-fast里面找。
测试
测试与整合商品服务里的mybatisplus

在common的pom.xml中导入
<!-- 数据库驱动 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>  # Tomcat有带,所以provided
</dependency>

删掉common里xss/xssfiler和XssHttpServletRequestWrapper
在product项目的resources目录下新建application.yml
spring:
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://192.168.1.17:3306/gulimall_pms?useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=Asia/Shanghai
    username: root
    password: root


# MapperScan
# sql映射文件位置
mybatis-plus:
  mapper-locations: classpath:/mapper/**/*.xml
  global-config:
    db-config:
      id-type: auto

然后在主启动类上加上注解@MapperScan()
@MapperScan("com.rabbitboss.gulimall.product.dao")
@SpringBootApplication
public class gulimallProductApplication {
   


    public static void main(String[] args) {
   

        SpringApplication.run(gulimallProductApplication.class, args);
    }

}

然后去测试,先通过下面方法给数据库添加内容
@SpringBootTest
class GulimallProductApplicationTests {
   

    @Autowired
    BrandService brandService;

    @Test
    void contextLoads() {
   

//        BrandEntity brandEntity = new BrandEntity();
//        brandEntity.setBrandId(1L);
//        brandEntity.setDescript("华为");

//        brandEntity.setDescript("");
//        brandEntity.setName("华为");
//        this.brandService.save(brandEntity);
//        System.out.println("保存成功!");

//        brandService.updateById(brandEntity);
//        System.out.println("修改成功!");

        List<BrandEntity> list = brandService.list(new QueryWrapper<BrandEntity>().eq("brand_id", 1L));
        list.forEach((item)->{
   
            System.out.println(item);
        });

    }

}
3.11.2coupon
重新打开generator逆向工程,修改generator.properties
# 主目录 
mainPath=com.rabbitboss
package=com.rabbitboss.gulimall
moduleName=coupon
autho=rabbitboss
email=xxx@qq.com
tablePrefix=sms_

修改yml数据库信息
spring:
  datasource:
    username: root
    password: root
    url: jdbc:mysql://192.168.1.17:3306/gulimall_sms?useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=Asia/Shanghai


mybatis-plus:
  mapper-locations: classpath:/mapper/**/*.xml
  global-config:
    db-config:
      id-type: auto
      logic-delete-value: 1
      logic-not-delete-value: 0

server:
  port: 7000

启动生成RenrenApplication.java,运行后去浏览器80端口查看,同样让他一
页全显示后选择全部后生成。生成后解压复制到coupon项目对应目录下。
让coupon也依赖于common,修改pom.xml

<dependency>
    <groupId>com.atguigu.gulimall</groupId>
    <artifactId>gulimall-common</artifactId>
    <version>0.0.1-SNAPSHOT</version>
</dependency>

resources下src包先删除

添加application.yml
spring:
  datasource:
    username: root
    password: root
    url: jdbc:mysql://192.168.1.17:3306/gulimall_sms?useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=Asia/Shanghai
    driver-class-name: com.mysql.cj.jdbc.Driver


mybatis-plus:
  mapper-locations: classpath:/mapper/**/*.xml
  global-config:
    db-config:
      id-type: auto
      logic-delete-value: 1
      logic-not-delete-value: 0

运行gulimallCouponApplication.java

http://localhost:8080/coupon/coupon/list

{
   "msg":"success","code":0,"page":{
   "totalCount":0,"pageSize":10,"totalPage":0,"currPage":1,"list":[]}}
3.11.3member
重新使用代码生成器生成ums

模仿上面修改下面两个配置
代码生成器里:
url: jdbc:mysql://192.168.1.17:3306/gulimall_sms?useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=Asia/Shanghai


mainPath=com.rabbitboss 
package=com.rabbitboss.gulimall
moduleName=member
author=rabbitboss
email=xxx@qq.com
tablePrefix=ums_

重启RenrenApplication.java,然后同样去浏览器获取压缩包解压到对应member项目目录

member也导入依赖
<dependency>
    <groupId>com.atguigu.gulimall</groupId>
    <artifactId>gulimall-common</artifactId>
    <version>0.0.1-SNAPSHOT</version>
</dependency>

同样新建application.yml
spring:
  datasource:
    username: root
    password: root
    url: jdbc:mysql://192.168.1.17:3306/gulimall-ums?useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=Asia/Shanghai
    driver-class-name: com.mysql.cj.jdbc.Driver


mybatis-plus:
  mapper-locations: classpath:/mapper/**/*.xml
  global-config:
    db-config:
      id-type: auto
      logic-delete-value: 1
      logic-not-delete-value: 0

server:
  port: 8000
order端口是9000,product是10000,ware是11000。
以后比如order系统要复制多份,他的端口计算9001、9002。。。

重启web后,http://localhost:8000/member/growthchangehistory/list
测试成功:{"msg":"success","code":0,"page":{"totalCount":0,"pageSize":10,"totalPage":0,"currPage":1,"list":[]}}
3.11.4order
修改代码生成器
jdbc:mysql://192.168.1.17:3306/gulimall_oms?useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=Asia/Shanghai

#代码生成器,配置信息
mainPath=com.rabbitboss
package=com.rabbitboss.gulimall
moduleName=order
author=rabbitboss
email=xxx@qq.com
tablePrefix=oms_


运行RenrenApplication.java重新生成后去下载解压放置。
application.yml

spring:
  datasource:
    username: root
    password: root
    url: jdbc:mysql://192.168.1.17:3306/gulimall_oms?useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=Asia/Shanghai
    driver-class-name: com.mysql.cj.jdbc.Driver


mybatis-plus:
  mapper-locations: classpath:/mapper/**/*.xml
  global-config:
    db
  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值