将项目所有模块(功能)打成jar或者war,然后部署一个进程
优点: 1:部署简单:由于是完整的结构体,可以直接部署在一个服务器上即可。
2:技术单一:项目不需要复杂的技术栈,往往一套熟悉的技术栈就可以完成开发。
缺点: 1:系统启动慢,一个进程包含了所有的业务逻辑,涉及到的启动模块过多,导致系统的启动、重启时间周期过长;
2:系统错误隔离性差、可用性差,任何一个模块的错误均可能造成整个系统的宕机;
3:可伸缩性差:系统的扩容只能只对这个应用进行扩容,无法结合业务模块的特点进行伸缩。
4: 线上问题修复周期长:任何一个线上问题修复需要对整个应用系统进行全面升级。
5: 跨语言程度差
6: 不利于安全管理,所有开发人员都拥有全量代码。
微服务架构论文: Microservices
译文: 微服务译文理解_微服务架构翻译_发了个版的博客-CSDN博客
简单来说,微服务架构风格[1]是一种将一个单一应用程序开发为一组小型服务的方法,每个服务运行在自己的进程中,服务间通信采用轻量级通信机制(通常用HTTP资源API)。这些服务围绕业务能力构建并且可通过全自动部署机制独立部署。这些服务共用一个最小型的集中式的管理,服务可用不同的语言开发,使用不同的数据存储技术。
> 一个项目被拆分若干个项目
> 每个项目可以独立运行
> 每个项目可以使用不同的语言开发
> 每个项目可以拥有独立的数据库
> 项目与项目之间可以通信[http协议]
解读微服务特点:
1:微服务是一种==项目架构思想==(风格)
2:微服务架构是一系列小服务的组合(组件化与多服务)
3:任何一个微服务,都是一个独立的进程(独立开发、独立维护、独立部署)
4:轻量级通信http协议(跨语言,跨平台)
5:服务粒度(围绕业务功能拆分---模块拆分【系统管理服务】【日志服务】【焦虑测试】【抑郁测试系统】
1.易于开发和维护
一个微服务只关注一个特定的业务功能,所以它的业务清晰、代码量较少。开发和维护单个微服务相对比较简单,整个应用是由若干个微服务构建而成,所以整个应用也会维持在可控状态;
⒉.单个微服务启动较快
单个微服务代码量较少,所以启动会比较快;
3.局部修改容易部署
单体应用只要有修改,就要重新部署整个应用,微服务解决了这样的问题。一般来说,对某个微服务进行修改,只需要重新部署这个服务即可;
4.技术栈不受限
在微服务中,我们可以结合项目业务及团队的特点,合理地选择技术栈
5.按需伸缩
焦虑系统访问量大,只需要对焦虑系统进行扩展
1、服务太多,导致服务间的依赖错综复杂,运维难度大
2、微服务放大了分布式架构的系列问题
分布式事务(seata)
分布式锁怎么处理(redisson) ,
服务注册与发现(nacos) .
依赖服务不稳定(sentinel)导致服务雪崩怎么办?
3、运维复杂度陡增,部署数量多、监控进程多导致整体运维复杂度提升。
如何解决上面的挑战----springcloud
Springcloud为微服务思想提供了完美的==解决方案==
Springcloud是一些列框架的集合体(不同的框架解决微服务面临的不同的挑战)
springcloud提供了两款模式:第一种netflix公司 第二款:alibaba-阿里巴巴。
SpringBoot专注于快速方便的开发单个个体微服务。
SpringCloud是关注全局的微服务协调、整理、治理的框架,它将SpringBoot开发的单体整合并管理起来。
SpringBoot可以离开SpringCloud独立使用开发项目,但是SpringCloud离不开SpringBoot,属于依赖关系。
技术栈:
mysql+mybatis[mp]+springboot+springcloud alibaba
订单数据库:
SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;-- ----------------------------
-- Table structure for shop_order
-- ----------------------------
DROP TABLE IF EXISTS `shop_order`;
CREATE TABLE `shop_order` (
`oid` bigint(0) NOT NULL AUTO_INCREMENT COMMENT '订单id',
`uid` int(0) NULL DEFAULT NULL COMMENT '用户id',
`username` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '用户名',
`pid` bigint(0) NULL DEFAULT NULL COMMENT '商品id',
`pname` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '商品名称',
`pprice` decimal(10, 2) NULL DEFAULT NULL COMMENT '商品价格',
`number` int(0) NULL DEFAULT NULL COMMENT '购买数量',
PRIMARY KEY (`oid`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 44956 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic;-- ----------------------------
-- Records of shop_order
-- ----------------------------SET FOREIGN_KEY_CHECKS = 1;
商品数据库
SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;-- ----------------------------
-- Table structure for shop_product
-- ----------------------------
DROP TABLE IF EXISTS `shop_product`;
CREATE TABLE `shop_product` (
`pid` bigint(0) NOT NULL AUTO_INCREMENT COMMENT '商品id',
`pname` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '商品名',
`pprice` decimal(10, 2) NULL DEFAULT NULL COMMENT '商品价格',
`stock` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '商品库存',
PRIMARY KEY (`pid`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 3 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic;-- ----------------------------
-- Records of shop_product
-- ----------------------------
INSERT INTO `shop_product` VALUES (1, '华为手机', 1999.00, '100');
INSERT INTO `shop_product` VALUES (2, 'vivo手机', 2999.00, '100');
INSERT INTO `shop_product` VALUES (3, '小米', 2222.00, '1000');SET FOREIGN_KEY_CHECKS = 1;
(1)依赖
4.0.0
com.ykq
qy165-springcloud-parent
1.0-SNAPSHOT
pom
org.springframework.boot
spring-boot-starter-parent
2.3.2.RELEASE
1.8
UTF-8
UTF- 8
Hoxton.SR8
2.2.3.RELEASE
org.springframework.cloud
spring-cloud-dependencies
${spring-cloud.version}
pom
import
com.alibaba.cloud
spring-cloud-alibaba-dependencies
${spring-cloud-alibaba.version}
pom
import
qy165-springcloud-parent
com.ykq
1.0-SNAPSHOT
4.0.0
qy165-springcloud-common
org.projectlombok
lombok
com.baomidou
mybatis-plus-boot-starter
3.5.1
(2)创建相应的实体类
@Data
@TableName(value = "shop_order")
public class Order implements Serializable {
@TableId(type = IdType.AUTO)
private Integer oid;
private Integer uid;
private String username;
private Integer pid;
private String pname;
private BigDecimal pprice;//double 精度丢失
private Integer number;
}
@Data
@TableName(value = "shop_product")
public class Product implements Serializable {
@TableId(value = "pid",type = IdType.AUTO)
private Integer pid;
private String pname;
private BigDecimal pprice;
private Integer stock;
}
com.ykq
qy165-springcloud-common
1.0-SNAPSHOT
org.springframework.boot
spring-boot-starter-web
mysql
mysql-connector-java
配置文件 application.properties
#端口号8001~8008
server.port=8001
#数据源
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.password=root
spring.datasource.username=root
spring.datasource.url=jdbc:mysql:///springcloud-product?serverTimezone=Asia/Shanghai
#sql日志打印控制台
mybatis-plus.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl
#mybatis映射文件
mybatis-plus.mapper-locations=classpath:/mapper/*.xml
主启动类
@SpringBootApplication
@MapperScan(basePackages = "com.aaa.product.dao")
public class ProductApplication {
public static void main(String[] args) {
SpringApplication.run(ProductApplication.class,args);
}
}
dao接口
public interface ProductDao extends BaseMapper {
}
service层
public interface ProductService extends IService {
Product selectProduct(Integer id);
}
@Service
public class ProductServiceImpl extends ServiceImpl implements ProductService {
@Resource
private ProductDao productDao;
@Override
public Product selectProduct(Integer id) {
Product product = productDao.selectById(id);
return product;
}
}
controller层
@RestController
@RequestMapping("/product")
public class ProductController {
@Autowired
private ProductService productService;
@GetMapping("/select/{id}")
public Product select(@PathVariable Integer id){
Product product = productService.selectProduct(id);
return product;
}
}
(1)依赖省略--
(2)配置省略--
(3)dao和service省略
(4)controller层
@RestController
@RequestMapping("/order")
public class OrderController {
@Autowired
private OrderService orderService;
@Resource
private RestTemplate restTemplate;
@GetMapping("insert/{pid}/{num}")
public String insert(@PathVariable Integer pid,@PathVariable Integer num){
Orders orders = new Orders();
orders.setUid(1);
orders.setUsername("yhl");
orders.setNumber(num);
//商品信息---调用商品微服务接口
//spring封装了http远程调用RestTemplate,默认没有交于spring管理,创建配置类,写一个@bean注解
/**
* String url, 远程调用服务器的地址
* Class responseType, 远程调用接口返回类型的反射类
* Object... uriVariables 远程接口需要传递的参数
*/
Product product = restTemplate.getForObject("http://localhost:8001/product/select/" + pid, Product.class);
orders.setPname(product.getPname());
orders.setPprice(product.getPprice());
orders.setPid(product.getPid());
int i = orderService.insert(orders);
if (i>0){
return "下单成功";
}
return "下单失败";
}
}