商城项目(一) -- 项目简介、基础搭建及前端部分

1. 项目简介

1.1 背景

电商相关模式:

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

1.2 谷粒商城架构图

商城项目(一) -- 项目简介、基础搭建及前端部分_第1张图片
商城项目(一) -- 项目简介、基础搭建及前端部分_第2张图片

前后分离开发,分为内网部署和外网部署,外网是面向公众访问的。
访问前端项目,可以有手机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容器的方式运行。

2. 分布式基础概念

2.1 微服务

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

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

2.2 集群&分布式&节点

  • 集群:是个物理状态,分布式是个工作方式,只要是一堆机器,也可以叫做集群,他们是不是一起协作干活,这谁也不知道。
  • 分布式:《分布式系统原理与范型》定义:分布式系统是若干独立计算机的集合,这些计算机对于用户来说像单个系统;分布式系统 (distributed system) 是建立网络之上的软件系统;
  • 节点:集群中的一个服务器

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

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

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

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

2.3 远程调用

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

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

2.4 负载均衡

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

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

常见的负载均衡算法:

  • 轮询:为第一个请求选择健康池中的每一个后端服务器,然后按顺序往后依
    次选择,直到最后一个,然后循环
  • 最小连接:优先选择链接数最少,也就是压力最小的后端服务器,在会话较
    长的情况下可以考虑采取这种方式

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

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

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

商城项目(一) -- 项目简介、基础搭建及前端部分_第3张图片

2.6 配置中心

商城项目(一) -- 项目简介、基础搭建及前端部分_第4张图片
每一个服务最终都有大量配置,并且每个服务都可能部署在多个服务器上,我们经常需要变更配置,我们可以让每个服务在配置中心获取自己的配置。

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

2.7 服务熔断&服务降级

在微服务架构中,微服务之间通过网络来进行通信,存在相互依赖,当其中一个服务不可用时,有可能会造成雪崩效应,要防止这种情况,必须要有容错机制来保护服务
商城项目(一) -- 项目简介、基础搭建及前端部分_第5张图片
rpc情景:
订单服务 --> 商品服务 --> 库存服务

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

  1. 服务熔断:设置服务的超时,当被调用的服务经常失败到达某个阈值,我们可以开启断路保护机制,后来的请求不再去调用这个服务,本地直接返回默认的数据
  2. 服务降级:在运维期间,当系统处于高峰期,系统资源紧张,我们可以让非核心业务降级运行,降级:某些服务不处理,或者简单处理【抛异常,返回NULL,调用 Mock数据,调用 FallBack 处理逻辑

2.8 api网关

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

3. 环境搭建,数据库初始化,项目架构搭建

3.1 环境搭建

  1. 服务器:阿里云服务器
  2. docker安装:docker安装
  3. docker的mysql及redis安装:mysql及redis安装
  4. maven安装及配置:安装不多说,在settings配置文件中添加:
在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>
  1. vscode、idea开发插件安装:安装不多说,安装完成后下载插件:
# 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
  1. git安装完成后,使用ssh免密连接
# 在win桌面启动git bash客户端

# 配置用户名
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 55533@qq.com

# 测试
ssh -T [email protected]

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

3.2 项目创建、数据库初始化

  1. gitee中创建仓库
    商城项目(一) -- 项目简介、基础搭建及前端部分_第6张图片

  2. 将创建好的项目通过git拉到idea中,不多说

  3. 项目及商城数据库表初始化,见项目中,不多说
    商城项目(一) -- 项目简介、基础搭建及前端部分_第7张图片

  4. gitignore排除文件,不多说

3.3 引入人人开源快速构建后台

  1. 这里我们到gitee上搜索人人开源,使用renren-fast和renren-fast-vue项目。
  2. 打开git bash客户端,通过git clone,我们将这两个项目拉到本地。
3.3.1 后台初始化
  1. 删除renren-fast中的.git文件,然后将项目复制到我们的商城项目的文件中去,这个就算是我们的后台项目
  2. 打开人人项目中的db文件,复制初始化sql到navicat中执行,初始化出后台表文件
  3. 在主pom中引入renren-fast子项目
<modules>
	<module>cmall-product</module>
	<module>cmall-member</module>
	<module>cmall-order</module>
	<module>cmall-product</module>
	<module>cmall-ware</module>
	<module>renren-fast</module>
</modules>
  1. 修改数据库连接信息和port后启动
io.renren.RenrenApplication              : Started RenrenApplication in 9.014 seconds (JVM running for 10.529)
3.3.2 前端项目初始化
  1. 安装node(帮助下载前端需要的一些包,有点类似于maven):下载node-v10.16.3-x64.msi版本 ,一路next
  2. 查看是否安装:node -v
  3. 使用淘宝镜像加速:npm config set registry http://registry.npm.taobao.org/
  4. 将renren-fast-vue项目删除.git文件,然后拖入到vscode中
  5. 打开vscode的终端,执行npm install下载前端项目需要的包
    商城项目(一) -- 项目简介、基础搭建及前端部分_第8张图片
  6. 如果出现以下报错:
7. 报错:
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

2. 解决报错:
先删除目录下的node_module文件,然后执行:npm install chromedriver --chromedriver_cdnurl=http://cdn.npm.taobao.org/dist/chromedriver
3. 再次执行npm install

4. 如果还是不行,查看你的node版本和项目中的node-sass版本是否一致,我的node是10.16.3,node-sass版本是4.9.0
  1. 完成后,全局搜索下8080端口,修改为8086,因为之前我们在后端已经修改为8086,然后npm run dev 启动,输入账号密码admin admin登陆
    商城项目(一) -- 项目简介、基础搭建及前端部分_第9张图片
3.3.3 使用逆向工程生成crud代码
  1. 从人人开源拉取renren-generator项目到本地

  2. 删除git文件,然后将generator项目拷贝到cmall项目中

  3. 修改application文件和generator.properties文件

  4. 启动renren-generator项目,打开后台管理
    商城项目(一) -- 项目简介、基础搭建及前端部分_第10张图片

  5. 选中需要生成代表的表,点击生成代码

  6. 将生成的文件解压复制到各个服务中,

  7. 新建common项目,拷贝renren-fast中的内容,作为通用服务,让各个服务引用通用服务,然后解决各个服务中的报错,看项目,不多说

3.4 启动测试

3.4.1 common中添加数据库连接

删掉common里xss/xssfiler和XssHttpServletRequestWrapper

在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>
3.4.2 编写yml文件

在product项目的resources目录下新建application.yml

spring:
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://192.168.1.103: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
3.4.3 测试
  1. 然后在主启动类上加上注解@MapperScan():
@MapperScan("com.yhx.cmall.product.dao")
  1. 然后去测试,先通过下面方法给数据库添加内容
@RunWith(SpringRunner.class)
@SpringBootTest
class CmallProductApplicationTests {

    @Autowired
    BrandService brandService;

    @Test
    void contextLoads() {
        BrandEntity brandEntity = new BrandEntity();
        brandEntity.setDescript("hello");
        brandEntity.setName("华为");
        brandService.save(brandEntity);
        System.out.println("保存成功");
    }
}

你可能感兴趣的:(项目,学习)