Java服务器项目分类
现在市面上常见的java开发的项目可以分为两大类
1.企业级应用
一般指一个企业或机构内部使用的网站或服务器应用程序
包括的领域很多,包括并不限于:商业,企事业单位,医疗,军事,政府,金融等
这种项目的特征是访问人数不多,不是全国乃至全世界都需要使用的网站
因为人数比较少又没有替代品,所以不强烈要求三高
但是企业级项目一般会有比较复杂的权限设置和业务流程
2.互联网应用
指对全国乃至全世界开放的网站或服务器引用程序
我们手机中安装的app大部分都是互联网应用
微信,支付宝,京东,淘宝,饿了么,美团,抖音,qq音乐,爱奇艺,高德地图等
他们因为商业竞争等各种原因,对服务器性能有要求,也就是前面提到的"三高"
及时并发量非常大,程序也要正常运行,迅速响应
互联网应用一般业务和权限相对简单,但是要求"三高"
因为上述java项目的分类偏重点不同
在当今java开发的业界中,有下面的基本规律
- 如果开发的是企业级应用,使用单体架构的情况比较多
- 如果开发的是互联网应用,使用微服务架构的情况比较多
什么是微服务
微服务是由以单一应用程序构成的小服务,自己拥有自己的行程与轻量化处理,服务依业务功能设计,以全自动的方式部署,与其他服务使用 HTTP API 通信。同时服务会使用最小的规模的集中管理能力,服务可以用不同的编程语言与数据库等组件实现。
简单来说,微服务就是将一个大型项目的各个业务代码,拆分成多个互不干扰的小项目,而这些小项目专心完成自己的功能,而且可以调用别的小项目的方法,从而完成整体功能
京东\淘宝这样的大型互联网应用程序,基本每个操作都是一个单独的微服务在支持:
- 登录服务器
- 搜索服务器
- 商品信息服务器
- 购物车服务器
- 订单服务器
- 支付服务器
- 物流服务器
- .....
为什么使用微服务
左侧小餐馆就像单体项目
一旦服务器忙,所有业务都无法快速响应
即使添加了服务器,也不能很好的解决这个问题
不能很好的实现"高并发,高可用,高性能"
但是因为服务器数量少,所以成本低,适合并发访问少的项目
右侧的大餐厅就是微服务项目
每个业务有专门一批人负责,业务之间互不影响
能够针对的在性能不足的业务上添加服务器来改善性能,同时万一一个服务器异常,不会影响整体功能
但是服务器数量多,成本高,适合要要求"高并发,高可用,高性能"的项目
怎么搭建微服务项目
在微服务概念提出之前(2014年),每个厂商都有自己的解决方案
但是Martin Fowler(马丁·福勒)提出了微服务的标准之后,为了技术统一和兼容性,很多企业开始支持这个标准
现在业界中开发微服务项目,大多数都是在这个标准下的
如果我们自己编写支持这个标准的代码是不现实的,必须通过现成的框架或组件完成满足这个微服务标准的项目结构和格式
当今程序员要想快速完成微服务标准的程序,首选SpringCloud
Spring Cloud
什么是Spring Cloud
SpringCloud是由Spring提供的一套能够快速搭建微服务架构程序的框架集
框架集表示SpringCloud不是一个框架,而是很多框架的统称
SpringCloud是为了搭建微服务架构的程序而出现的
有人将SpringCloud称之为"Spring全家桶",广义上指代所有Spring的产品
SpringCloud的内容
从内容提供者角度
- Spring自己编写的框架和软件
- Netflix(奈非):早期提供了很多(全套)微服务架构组件
- alibaba(阿里巴巴):新版本SpringCloud推荐使用(正在迅速占领市场)
课程中大量使用alibaba的微服务组件
从功能上分类
- 微服务的注册中心
- 微服务间的调用
- 微服务的分布式事务
- 微服务的限流
- 微服务的网关
安装启动Nacos
将下载好的Nacos压缩包解压
将压缩包解压(注意不要有中文路径或空格)
打开解压得到的文件夹后打开bin目录会有如下内容
cmd结尾的文件是windows版本的
sh结尾的文件是linux和mac版本的
startup是启动文件,shutdown是停止文件
Windows下启动Nacos不能直接双击cmd文件
需要进入dos命令运行
在当前资源管理器地址栏输入cmd
G:\pgm\nacos\bin>startup.cmd -m standalone
-m是设置启动方式参数
standalone翻译为标准的孤独的
意思是单机模式标准运行
运行成功默认占用8848端口,并且在代码中提示
如果不输入standalone运行会失败
startup.cmd -m standalone
验证Nacos的运行状态
打开浏览器输入http://localhost:8848/nacos
如果是首次访问,会出现这个界面
登录系统
用户名:nacos
密码:nacos
登录之后可以进入后台列表
不能关闭启动nacos的dos窗口
我们要让我们编写的项目注册到Nacos,才能真正是微服务项目
所谓注册中心,其实是分布式架构演进过程中的产物,在系统中充当一个协调者的角色。但是,为什么需要这样一个协调者的角色呢?我们先来看一个例子,以便理解为什么分布式架构中需要有注册中心。
案例
小明和小新住在同一家沃尔玛超市附近,他俩都办了会员,经常关注超市的一些优惠活动,元宵节快到了,沃尔玛准备搞一个元宵节特惠活动,需要通知到附近的住户。对于沃尔玛来说,可以安排工作人员电话通知到小明和小新;而对于小明和小新来说,可以去超市咨询相关信息。
那么问题来了,住在超市附近的,不只有小明和小新两个消费者,如果每个人都打电话去通知就显得太麻烦了,小明和小新提前在超市了解了相关信息,可是不巧的是,由于各种原因,沃尔玛元宵特惠活动要从上午改到下午才开始,他们又该从何得知呢?
其实,沃尔玛关心的是通知能不能传达到附近的住户,小明和小新关心的是沃尔玛优惠活动的详情动态。沃尔玛不必给每个住户挨个电话通知,它只需要在它的微信公众号上推送一条消息即可,小明和小新也不用去超市咨询,只要随时关注沃尔玛公众号的推送消息即可。
在上面这个例子中,沃尔玛就是服务提供者,小明和小新是服务消费者,微信公众号类似于注册中心,沃尔玛将“服务”发布到注册中心,小明和小新作为消费者,订阅注册中心上沃尔玛提供的“服务”,通过微信公众号,沃尔玛(服务方)和小明、小新(消费方)就“解耦”了。
用这个例子来解释注册中心未必恰当,毕竟系统中的服务既可以是服务提供者(Provider),也可以是服务消费者(Consumer),但我想的是以一种更加通俗的方式来解释它,技术日新月异,各种技术、术语层出不穷,容易让人头晕眼花,但万变不离其宗,技术源于现实世界,亦服务于现实世界,在现实世界中,我们思考如何解决问题,技术也必然以同样的思路去解决问题。
业务概述
这个项目作为学习微服务组件使用
我们需要完成一个添加订单的业务
模拟用户选中购物车中商品并且确定了数量的情况下点击提交订单时后端的操作
1.减少选中商品sku的库存数
2.删除用户再购物车中勾选的商品
3.生成订单,将订单信息保存到数据库
上面三个步骤分别由3个模块完成
- 库存模块:减少库存
- 购物车模块:删除购物车信息
- 订单模块:新增订单
下面就开始搭建这个项目
创建csmall父项目
创建项目名称csmall
首先删除项目的src目录,因为我们使用不到
其次,pom文件有大量配置
直接从提供给大家的完整版中复制
其中的内容,我们会随着后面学习,逐一给大家讲解
最终的pom文件内容为
<?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>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.5.4</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>cn.tedu</groupId>
<artifactId>csmall</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>csmall</name>
<description>微服务框架演示案例</description>
<packaging>pom</packaging>
<modules>
<!-- <module>csmall-business</module>-->
<!-- <module>csmall-commons</module>-->
<!-- <module>csmall-cart</module>-->
<!-- <module>csmall-order</module>-->
<!-- <module>csmall-stock</module>-->
</modules>
<properties>
<java.version>1.8</java.version>
<spring-cloud.version>2020.0.3</spring-cloud.version>
<spring-cloud-alibaba.version>2.2.2.RELEASE</spring-cloud-alibaba.version>
<spring-boot.version>2.5.4</spring-boot.version>
<spring-boot-configuration-processor.version>2.3.0.RELEASE</spring-boot-configuration-processor.version>
<spring-security-jwt.version>1.0.10.RELEASE</spring-security-jwt.version>
<mybatis-spring-boot.version>2.2.0</mybatis-spring-boot.version>
<mybaits-plus.version>3.4.1</mybaits-plus.version>
<pagehelper-spring-boot.version>1.4.0</pagehelper-spring-boot.version>
<mysql.version>8.0.26</mysql.version>
<lombok.version>1.18.20</lombok.version>
<knife4j-spring-boot.version>2.0.9</knife4j-spring-boot.version>
<spring-rabbit-test.version>2.3.10</spring-rabbit-test.version>
<spring-security-test.version>5.5.2</spring-security-test.version>
<fastjson.version>1.2.45</fastjson.version>
<druid.version>1.1.20</druid.version>
<jjwt.version>0.9.0</jjwt.version>
<seata-server.version>1.4.2</seata-server.version>
</properties>
<dependencies>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
</dependencies>
<!-- 依赖管理 -->
<dependencyManagement>
<dependencies>
<!--seata-all-->
<dependency>
<groupId>io.seata</groupId>
<artifactId>seata-all</artifactId>
<version>${seata-server.version}</version>
</dependency>
<!-- Lombok -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>${lombok.version}</version>
</dependency>
<!-- MySQL -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>${mysql.version}</version>
<scope>runtime</scope>
</dependency>
<!-- Alibaba Druid -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>${druid.version}</version>
</dependency>
<!-- MyBatis Spring Boot:数据访问层MyBatis编程 -->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>${mybatis-spring-boot.version}</version>
</dependency>
<!-- MyBatis Plus Spring Boot:MyBatis增强 -->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>${mybaits-plus.version}</version>
</dependency>
<!-- MyBatis Plus Generator:代码生成器 -->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-generator</artifactId>
<version>${mybaits-plus.version}</version>
</dependency>
<!-- PageHelper Spring Boot:MyBatis分页 -->
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper-spring-boot-starter</artifactId>
<version>${pagehelper-spring-boot.version}</version>
</dependency>
<!-- Spring Boot:基础框架 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
<version>${spring-boot.version}</version>
</dependency>
<!-- Spring Boot Web:WEB应用 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>${spring-boot.version}</version>
</dependency>
<!-- Spring Boot Freemarker:MyBaits Plus Generator的辅助项 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-freemarker</artifactId>
<version>${spring-boot.version}</version>
</dependency>
<!-- Spring Boot Validation:验证请求参数 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
<version>${spring-boot.version}</version>
</dependency>
<!-- Spring Boot Security:认证授权 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
<version>${spring-boot.version}<