1)、电商模式
市面上有5种常见的电商模式:B2B、B2C、C2B、C2C、O2O;
Business to Business,是指商家之间的商业关系,如:阿里巴巴;
Business to Consumer,就是我们经常看到的供应商直接把商品卖给用户,即“商对客”模式,也就是通常说的商业零售,直接面向消费者销售产品和服务。如:苏宁易购、京东、天猫等;
Customer to Business,即消费者对企业。先有消费者提出需求,后有企业组织生产;
Customer to Consumer,客户之间的交易,如:淘宝、咸鱼等;
Online to Offline,即是将线下商务的机会与互联网结合,让互联网称为线下交易的前台。线上快速支付,线下优质服务。如:饿了么、美团、淘票票、京东到家等;
微服务架构风格,就像是把一个单独的应用程序开发为一套小服务,每个小服务运行在自己的进程中,并使用轻量级机制通信,通常是HTTP API。这些服务围绕业务能力来构建,并通过完全自动化部署机制来独立部署。这些服务可以使用不同的编程语言书写,以及不同数据存储技术,并保持最低限度的集中式管理。
简而言之:拒绝大型单体应用,基于业务边界进行服务微化拆分,各个服务独立部署运行。
集群是个物理形态,分布式是个工作方式。
只要是一堆机器,就可以叫集群,他们是不是一起协作工作,这个谁也不知道。
《分布式系统原理与规范》
定义:
“分布式系统是若干独立计算机的集合,这些计算机对于用户来说就像单个相关系统”
分布式系统(distribution system)是建立在网络之上的软件系统。
分布式是指将不同的业务分布在不同的地方。
集群是指将几台服务器集中在一起,实现同一业务。
例如:京东是一个分布式系统,众多业务运行在不同的机器,所有业务构成一个大型业务集群。每一个小的业务,比如用户系统,访问压力大时一个服务器不够用,我们就应该将用户系统部署到多个服务器,也就是每一个业务系统都可以做集群。
分布式中的每一个节点都可以做集群。集群并不一定是分布式。
节点:集群中的一个服务器。
在分布式系统中,各个服务可能处于不同主机,但服务之间不可避免要互相调用,我们称为远程调用。
SpringCloud中使用HTTP + JSON的方式来完成远程调用
分布式系统中,A服务调用B服务,B服务部署集群,A调用任意一个均可完成功能。
为了使每一台服务器都不要太忙或太闲,我们可以负载均衡的调用每一个服务器,提升网站的健壮性。
常见的负载均衡算法:
**轮询:**按照顺序访问每一台服务器。
**最小连接:**优先选择连接数最少,也就是压力最小的服务器。
**散列:**根据请求源IP的hash值来选择要转发的服务器。可以解决session的问题。
A服务调用B服务,但不知道B服务在哪台服务器上,哪些是正常或下线的。解决这个问题可以引入注册中心;
每一个服务最终都有大量配置,并且每个服务都可能部署在多台服务器上。我们经常需要变更配置,因此工作量巨大。我们可以引入配置中心,让每个服务在配置中心获取自己的配置。
**配置中心用来集中管理微服务的配置信息 **
在微服务架构中,微服务之间通过网络通信,存在相互依赖,当一个服务不可用,有可能出现雪崩效应。要防止这样的情况,必须要有容错机制。
1)、服务熔断
设置服务的超时,当被调用的服务经常失败到达某个阈值,我们可以开启断路保护机制,后来的请求不再去调用这个服务。本地直接返回默认数据。
2)、服务降级
在运维期间,当系统处于高峰期,系统资源紧张,我们可以让非核心业务奖及运行。
降级:某些服务不处理,或者简单处理——抛异常 | 返回Null、调用Mock数据、调用faullback处理逻辑。
在微服务架构中,API Gateway作为整体架构的重要组件,它抽象了微服务中都需要的功能,同时提供客户端负载均衡,服务自动熔断,灰度发布,统一认证,限流留空、日志统计等丰富功能,帮助我们解决很多API管理难题。
安装Linux虚拟机
本次项目使用阿里的云服务器:ip:112.124.32.136
安装docker
docker安装mysql
docker安装redis
版本: 3.5.2
配置阿里云镜像
<mirrors>
<mirror>
<id>nexus-aliyunid>
<mirrorOf>centralmirrorOf>
<name>Nexus aliyunname>
<url>http://maven.aliyun.com/nexus/content/groups/publicurl>
mirror>
mirrors>
配置jdk1.8编译项目
<profiles>
<profile>
<id>jdk-1.8id>
<activation>
<activeByDefault>trueactiveByDefault>
<jdk>1.8jdk>
activation>
<properties>
<maven.compiler.source>1.8maven.compiler.source>
<maven.compiler.target>1.8maven.compiler.target>
<maven.compiler.compilerVersion>1.8maven.compiler.compilerVersion>
properties>
profile>
profiles>
idea安装插件:
lombok
mybatisx
vscode安装插件:
下载:https://git-scm.com
配置用户名和邮箱
进入git bash
#配置用户名
git config --global user.name "username"
#配置邮箱
git config --global user.email "[email protected]"
配置ssh免密登录
进入git bash
ssh-keygen -t rsa -C "注册git的邮箱"
# 三次回车结束
#查看
#一般用户目录会生成
id_rsa
id_rsa.pub
#或者输入命令
cat ~/.ssh/id_rsa.pub
#登录gitee,在设置里找到SSH KEY将.pub文件内容贴进去
#测试是否成功
ssh -T [email protected]
创建git仓库
打开gitee,新建仓库
名称:爽易购商城
路径:https://gitee.com/candy-xiaojing/shuang-tesco-mall.git
创建idea工程
打开idea,新建项目:shuang-tesco-mall
选择来自版本控制的项目
商品服务、仓储服务、订单服务、优惠券服务、用户服务
共同:
.gitignore添加以下内容
**/mvnw
**/mvnw.cmd
**/.mvn
**/target/
.idea
**/.gitignore
提交:
本项目的后台管理系统采用人人开源提供的后台系统快速进行搭建
进入gitee.com,搜索人人开源
renren-fast是基于Java的后台管理系统服务端代码
renren-fast-vue是基于vue的前端代码
部署进项目,启动
接下来使用renren-generator对各个模块进行代码生成
成功生成!
接下来创建公共模块shuang-common
<dependency>
<groupId>com.baomidougroupId>
<artifactId>mybatis-plus-boot-starterartifactId>
<version>3.4.2version>
dependency>
<dependency>
<groupId>org.projectlombokgroupId>
<artifactId>lombokartifactId>
<version>1.18.22version>
dependency>
<dependency>
<groupId>mysqlgroupId>
<artifactId>mysql-connector-javaartifactId>
<version>8.0.21version>
dependency>
<dependency>
<groupId>javax.servletgroupId>
<artifactId>servlet-apiartifactId>
<version>2.5version>
<scope>providedscope>
dependency>
<dependency>
<groupId>org.apache.httpcomponentsgroupId>
<artifactId>httpcoreartifactId>
<version>4.4.15version>
dependency>
<dependency>
<groupId>commons-langgroupId>
<artifactId>commons-langartifactId>
<version>${commons.lang.version}version>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-aopartifactId>
dependency>
<dependency>
<groupId>com.baomidougroupId>
<artifactId>mybatis-plus-boot-starterartifactId>
<version>3.4.2version>
dependency>
配置数据源
1)、导入数据库驱动
<dependency>
<groupId>mysqlgroupId>
<artifactId>mysql-connector-javaartifactId>
<version>8.0.21version>
dependency>
2)、在application.yml中配置数据源
spring:
# 数据源配置
datasource:
type: com.alibaba.druid.pool.DruidDataSource
driverClassName: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://112.124.32.136:3306/shuang_oms?useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=Asia/Shanghai
username: root
password: root
配置mybatis-plus
1)、启动类添加MapperScan注解
@MapperScan("com.qhit.shuang.product.dao") //dao层接口全路径
2)、application.yml中配置sql映射文件位置
mybatis-plus:
mapper-locations: classpath:/mapper/**/*.xml
SpringCloud的几大痛点
SpringCloud Alibaba的优势
结合Alibaba最终的技术搭配方案
注册中心
(服务发现和注册)配置中心
(动态配置管理)负载均衡
远程调用
(声明式HTTP客户端)服务容错
(限流、降级、熔断)网关
(webflux编程模式)调用链监控
分布式事务
解决方案github地址:https://github.com/alibaba/spring-cloud-alibaba
版本对应关系
Nacos是阿里巴巴开源的一个更易于构建云原生应用的动态服务发现、配置管理和服务管理平台。使用Java编写,依赖Java环境
Nacos文档地址:https://nacos.io/zh-cn/docs/quick-start.html
下载nacos-server
https://github.com/alibaba/nacos/releases
启动nacos-server
github文档:https://github.com/alibaba/spring-cloud-alibaba/wiki/Nacos-discovery
<dependency>
<groupId>com.alibaba.cloudgroupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discoveryartifactId>
dependency>
spring:
cloud:
nacos:
discovery:
# 连接注册中心进行注册
server-addr: 127.0.0.1:8848
application:
# 注册时的名字
name: 服务名
引入open-feign
依赖
<dependency>
<groupId>org.springframework.cloudgroupId>
<artifactId>spring-cloud-starter-openfeignartifactId>
dependency>
编写本地接口
作为远程方法映射
@FeignClient("服务名:application.name")
public interface 接口名:自定义|示例:feign/UserFeignService.java {
@RequestMapping("远程方法全路径")
public R list(@RequestParam Map<String, Object> params); // 远程方法签名
}
开启远程调用功能
启动类上添加注解
@EnableFeignClients(basePackages = "映射接口所在包的全路径,以‘.’分隔")
github文档:https://github.com/alibaba/spring-cloud-alibaba/wiki/Nacos-config
引入依赖
<dependency>
<groupId>com.alibaba.cloudgroupId>
<artifactId>spring-cloud-starter-alibaba-nacos-configartifactId>
dependency>
bootstrap.properties
spring.application.name=当前服务名
spring.cloud.nacos.config.server-addr=127.0.0.1:8848
创建服务端配置
RefreshScope
在Controller类名上配上RefreshScope注解
使用Value注解获取配置时可以动态刷新
细节
命名空间: 不同的命名空间下,可以存在相同的Group和Data ID,常用场景之一是不同环境的配置区分隔离,例如开发测试环境和生产环境的资源隔离等。
在bootstrap文件中修改要使用的命名空间
# 不配即默认:public空间
spring.cloud.nacos.config.namespace=命名空间ID(一长串)
配置集: 一组相关或不相关的配置项的集合称为配置集
配置组: 不同的Group下可以有相同的Data ID,相互隔离
在bootstrap文件中修改要使用的组名
spring.cloud.nacos.config.group=组名
配置集ID: 类似文件名,Data ID
在bootstrap文件中修改要使用的ID
spring.cloud.nacos.config.data-id=id名
最终配置:
spring.application.name=服务名
spring.cloud.nacos.config.server-addr=127.0.0.1:8848
# 服务自动加载 服务名.properties
# 默认加载默认空间和默认分组中的
# 指定了空间和组名后,会去取消默认,精确加载,若未找到,会去本地配置加载
spring.cloud.nacos.config.namespace=1eb9d3f3-ba68-43db-828b-784ac3e4859c
spring.cloud.nacos.config.group=组名
# extension-configs[0]:加载的第一个文件的配置
#获取当前命名空间下组名为test_group的data-id,并设置动态刷新
spring.cloud.nacos.config.extension-configs[0].data-id=data-id名
spring.cloud.nacos.config.extension-configs[0].group=DEFAULT_GROUP
spring.cloud.nacos.config.refresh-enabled=true
当请求到达网关,网关会断言请求是否符合某个路由规则,若符合,就按照路由规则将请求路由到指定服务,中间会经过一系列过滤器
断言文档:https://docs.spring.io/spring-cloud-gateway/docs/2.2.9.RELEASE/reference/html/#gateway-request-predicates-factories
过滤器文档:https://docs.spring.io/spring-cloud-gateway/docs/2.2.9.RELEASE/reference/html/#gatewayfilter-factories
<dependency>
<groupId>org.springframework.cloudgroupId>
<artifactId>spring-cloud-starter-gatewayartifact>
dependency>
spring:
cloud:
gateway:
routes:
- id: after_route # 路由id
uri: https://example.org #路由地址
predicates:
#After断言:会匹配指定时间点之后的请求
- After=2017-01-20T17:42:47.789-07:00[America/Denver]
spring:
cloud:
gateway:
routes:
- id: add_request_header_route # 路由id
uri: https://example.org #路由地址
filters:
# 添加请求头过滤器:将为请求头添加red,blue键值对
- AddRequestHeader=X-Request-red, blue
前端使用Vue
和ElementUI
vue官网文档:https://cn.vuejs.org/v2/guide/
ElementUI官网文档:https://element-plus.gitee.io/zh-CN/
Vue组件模板:https://www.cnblogs.com/songjilong/p/12635448.html
<el-button
type="text"
size="mini"
@click="append(data)"
v-if="node.level < 3"
<dependency>
<groupId>com.alibaba.cloudgroupId>
<artifactId>spring-cloud-starter-alicloud-ossartifactId>
<version>2.1.0.RELEASEversion>
dependency>
spring:
cloud:
alicloud:
access-key: your-ak
secret-key: your-sk
oss:
endpoint: oss-cn-hangzhou.aliyuncs.com #地域节点,此为示例
ElementUI表单校验:https://element.eleme.cn/#/zh-CN/component/form
Form 组件提供了表单验证的功能,只需要通过 rules 属性传入约定的验证规则,并将 Form-Item 的 prop 属性设置为需校验的字段名即可。校验规则参见 async-validator
还可以自定义校验规则:
前端校验方便用户的同时,也减轻了服务器压力
但当恶意访问者绕过浏览器,通过Postman等类似工具进行访问时,前端校验未必有用,此时我们需要添加后端校验
我们此次使用JSR303
自定义错误码以便快速精确定位错误
放在公共模块以便所有模块使用
BizCodeEnume
ExceptionControllerAdvice.java
**问题描述:**在github上clone下的项目执行npm install时报python环境错误
确保windows已安装node.js/vue/vue-cli
一、cmd下运行npm install -globabl -production windows-build-tools一键安装
二、在控制台输入:npm install -g node-gyp安装node-gyp
三、安装后检查:node-gyp list
最后到项目下执行npm install…成功。。。
后记:
如果还是提示“python找不到或者环境不对”
npm config set python C:\Users\Administrator\.windows-build-tools\python27\python.exe
跨域:指的是浏览器不能执行其他网站的脚本。它是由浏览器的同源策略造成的,是浏览器对JavaScript施加的安全限制。
同源策略:是指协议,域名,端口都要相同,其中有一个不同都会产生跨域。
解决方案一:使用Nginx部署为同一域
解决方案二:配置当前请求允许跨域