微服务概述
软件架构的演变:单体架构、垂直应用架构、流式计算架构 SOA、微服务架构和服务网格。
微服务是一种软件开发架构,它将一个大型应用程序拆分为一系列小型、独立的服务。每个服务都可以独立开发、部署和扩展,并通过轻量级的通信机制进行交互。
微服务架构的目标是提高系统的可伸缩性、灵活性和可维护性,同时降低开发和部署的复杂性。每个微服务都专注于一个特定的业务功能,并可以使用不同的编程语言和技术栈进行开发。这种分布式架构可以帮助团队更快地开发和部署新功能,同时减少对整个系统的影响。
Spring Cloud 是一个用于构建分布式系统的开发工具集合,它基于 Spring 框架,提供了一系列的解决方案和工具,用于简化分布式系统的开发和部署。Spring Cloud 提供了诸如服务注册与发现、负载均衡、断路器、配置管理等功能,使得开发人员可以更轻松地构建和管理分布式系统。
提供的组件有:分布式及版本化配置管理;服务注册与发现;服务路由、服务调用、负载均衡;断路器;全局锁;选举和集群状态管理;分布式消息。
Spring Cloud 实际上是一个整合各大公司开源技术的微服务开发规范,通过 SpringBoot 框架进行封装后屏蔽复杂的配置,给开发者提供开箱即用的开发体验,而 SpringCloud Neflix、SpringCloud alibaba才是 SpringCloud 规范的实现。
Spring Cloud Alibaba 是在 Spring Cloud 基础上集成了阿里巴巴的开源项目,提供了更多的分布式系统解决方案。它包含了诸如服务注册与发现、负载均衡、断路器、配置管理等功能,同时还提供了阿里巴巴的分布式事务解决方案、消息队列等特性。Spring Cloud Alibaba 可以与 Spring Cloud 无缝集成,为开发人员提供更多的选择和灵活性,帮助构建高可靠、高性能的分布式系统。
Spring Cloud Alibaba 的组件包括:
-
Nacos:服务注册和发现中心,提供了服务的注册、发现、配置和管理等功能。
-
Sentinel:流量控制和熔断降级组件,用于保护服务的稳定性和可靠性。
-
RocketMQ:分布式消息队列,用于实现异步通信和解耦系统之间的依赖关系。
-
Alibaba Cloud OSS:对象存储服务,用于存储和管理大量的非结构化数据。
-
Alibaba Cloud ACM:配置管理中心,用于集中管理应用程序的配置信息。
-
Alibaba Cloud SMS:短信服务,用于实现短信发送和接收功能。
-
Alibaba Cloud Dubbo:RPC 框架,用于实现服务之间的远程调用。
DevOps 是一种软件开发和运维的方法论,旨在通过自动化和协作来加速软件交付和提高系统的稳定性。DevOps 将开发团队和运维团队紧密合作,通过自动化工具和流程来实现持续集成、持续交付和持续部署。它强调文化的变革,包括团队合作、知识共享和持续改进。
DevOps 的目标是通过减少手动工作、减少错误和提高交付速度来提高软件交付的质量和效率。
微服务和 DevOps 之间的关系是相辅相成的。微服务架构提供了可独立部署的服务单元,而 DevOps提供了自动化和协作的能力,使得团队能够高效地开发、部署和维护这些微服务。它们共同促进了软件交付的质量、效率和可靠性。
领域驱动设计 DDD 是一种软件开发方法论,旨在通过将业务领域的专业知识融入到软件设计中来解决复杂业务问题。DDD 强调将软件系统划分为不同的领域,并将业务逻辑和领域模型作为核心驱动因素。它鼓励开发团队与领域专家紧密合作,共同理解业务需求,并将这些需求转化为领域模型和领域驱动设计的实现。DDD 提供了一些概念和模式,例如聚合根、实体、值对象、领域事件等,以帮助开发人员更好地理解和设计复杂的业务逻辑。
DDD 的目标是提高软件系统的可维护性、可扩展性和灵活性,以满足不断变化的业务需求。
RestTemplate
RestTemplate 是一个用于进行 HTTP 请求的 Java 类库,通常用于与 RESTful API 进行交互。它提供了一组简单而强大的方法,使得发送 HTTP 请求、处理响应和解析数据变得容易。使用 RestTemplate可以执行各种 HTTP 操作,如 GET、POST、PUT、DELETE 等。
1、创建 RestTemplate 实例:
RestTemplate restTemplate = new RestTemplate();
2、发送 GET 请求并获取响应:
ResponseEntity<String> response = restTemplate.getForEntity(url, String.class);
String obj=restTemplate.getForObject(url,String.class);
3、发送 POST 请求并获取响应:
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
设置相应内容类型
HttpEntity<String> requestEntity = new HttpEntity<>(requestBody, headers);
ResponseEntity<String> response = restTemplate.postForEntity(url, requestEntity, String.class);
4、发送 PUT 请求并获取响应:
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
HttpEntity<String> requestEntity = new HttpEntity<>(requestBody, headers);
restTemplate.put(url, requestEntity);
5、发送 DELETE 请求并获取响应:
restTemplate.delete(url);
通过 RestTemplate 可以方便地设置请求头、请求参数、请求体等,并处理响应结果。也可以使用RestTemplate 的其他方法来处理不同类型的请求和响应。但是需要注意的是,RestTemplate 在 Spring5.x 版本中已被宣布为过时,并计划在将来的版本中移除。建议在新的项目中使用 Spring WebClient或其他替代方案
git 并行版本控制
Git 是世界上最先进的分布式版本控制系统,克隆一个项目的速度非常快
每个开发都可以从 master 上克隆一个本地版本库,就算没有网络,也可以提交代码到本地仓库、查看 log、创建项目分支等。每个版本库都可以创建无限个分支,分支是个完整的目录,且这个目录拥有完整的实际文件
远程中央库 gitee.com
Nacos 服务治理
Nacos 即 Naming and Configuration Service 是一个用于动态服务发现、配置管理和服务元数据的开源平台。提供了统一的服务注册和发现、配置管理和元数据管理的功能,可以帮助开发人员更轻松地构建云原生应用和微服务架构。
Nacos 的主要功能包括:
-
服务注册和发现:Nacos 允许服务实例向注册中心注册自己的信息,并且其他服务可以通过查询注册中心来发现可用的服务实例。
-
配置管理:Nacos 提供了一个中心化的配置管理平台,可以动态地管理应用程序的配置信息。开发人员可以在运行时更新配置,而不需要重启应用程序。
-
服务元数据管理:Nacos 可以帮助开发人员管理服务的元数据,包括版本号、权重、健康状态等。这些元数据可以用于服务路由、负载均衡等场景。
-
动态 DNS 服务:Nacos 支持将服务名称解析为具体的网络地址,从而实现动态 DNS 服务的功能
Nacos 工作原理
-
服务注册:服务提供者在启动时向 Nacos 注册中心注册自己的服务信息,包括服务名称、IP 地址和端口号等。注册完成后,Nacos 将服务信息保存在自己的注册表中。
-
服务发现:服务消费者在需要调用某个服务时,向 Nacos 注册中心发送服务名称的请求。Nacos根据服务名称从注册表中查找对应的服务提供者信息,并将其返回给服务消费者。
-
服务健康检查:Nacos 会定期向服务提供者发送心跳检查请求,以确保服务的可用性。如果某个服务提供者长时间未响应心跳检查,Nacos 会将其标记为不可用,并从注册表中移除。
-
动态配置管理:Nacos 提供了配置中心的功能,可以将应用程序的配置信息存储在 Nacos 中,并实现动态的配置更新。应用程序可以通过订阅配置的方式,实时获取最新的配置信息。
-
负载均衡:Nacos 可以根据注册表中的服务提供者信息,实现负载均衡的功能。当服务消费者需要调用某个服务时,Nacos 会根据负载均衡策略选择一个可用的服务提供者。
Nacos 和 Eureka
Nacos 和 Eureka 都是服务发现和注册中心,用于管理和协调分布式系统中的服务实例。
主要区别:
-
开发和维护:Nacos 是阿里巴巴集团开发和维护的开源项目,而 Eureka 是 Netflix 开发和维护的开源项目。
-
功能和生态系统:Nacos 提供了服务注册、发现、配置管理和动态 DNS 等功能,同时还提供了更丰富的生态系统,如分布式配置、服务熔断、流量管理等。Eureka 主要关注服务注册和发现的功能。
-
一致性协议:Nacos 使用基于 Raft 协议的一致性算法来保证数据的一致性和高可用性。而 Eureka使用了 CAP 原理中的 AP 可用性和分区容错性模型,牺牲了一致性。
-
社区支持和发展:Nacos 在中国社区有着广泛的支持和活跃的发展,有大量的用户和贡献者。而Eureka 在国际社区有更广泛的应用和支持。
-
生态整合:Nacos 可以与 Spring Cloud、Dubbo 等广泛使用的开发框架进行无缝整合。Eureka 也与 Spring Cloud 紧密结合,并且在 Netflix 的微服务套件中有更多的组件和工具可用。
总体而言,Nacos 提供了更多的功能和生态系统,而 Eureka 则更专注于服务注册和发现的功能。选择使用哪个取决于项目的需求和团队的偏好。
数据库设计
SPU 标准产品单位是商品信息聚合的最小单位,是一组可复用、易检索的标准化信息的集合,该集合描述了一个产品的特性。如 iPhone X 可以确定一个产品即为一个 SPU,SPU 是由品牌+型号+关键属性构成的SKU 库存量单位。如 iPhone X 64G 银色 则是一个 SKU
针对电商而言:
1、SKU 是指一款商品,每款都有出现一个 SKU,便于电商品牌识别商品。
2、一款商品多色,则是有多个 SKU,例一件衣服,有红色、白色、蓝色,则 SKU 编码也不相同,如相同则会出现混淆,发错货。
分类表设计如下:
CREATE TABLE `category` (`id` int(20) NOT NULL AUTO_INCREMENT COMMENT '分类 ID', `name` varchar(50) DEFAULT NULL COMMENT '分类名称', `sort` int(11) DEFAULT NULL COMMENT '排序', `parent_id` int(20) DEFAULT NULL COMMENT '上级 ID', PRIMARY KEY (`id`),KEY `parent_id` (`parent_id`)
) ENGINE=InnoDB AUTO_INCREMENT=11182 DEFAULT
CHARSET=utf8 COMMENT='商品类目';
分类选择完成后,需要加载品牌,品牌加载并非一次性加载完成,而是根据选择的分类进行加载。
分类品牌关系表:
DROP TABLE IF EXISTS `category_brand`;
CREATE TABLE `category_brand` (`category_id` int(11) NOT NULL COMMENT '分类 ID',`brand_id` int(11) NOT NULL COMMENT '品牌 ID', PRIMARY KEY (`brand_id`,`category_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
品牌表:
CREATE TABLE `brand` ( `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '品牌 id', `name` varchar(100) NOT NULL COMMENT '品牌名称', `image` varchar(1000) DEFAULT '' COMMENT '品牌图片地址', `initial` varchar(1) DEFAULT '' COMMENT '品牌的首字母', `sort` int(11) DEFAULT NULL COMMENT '排序', PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=14 DEFAULTCHARSET=utf8 COMMENT='品牌表';
当选择分类后,会加载分类对应的属性。
分类属性表:
DROP TABLE IF EXISTS `category_attr`;
CREATE TABLE `category_attr` (`category_id` int(11) NOT NULL,`attr_id` int(11) NOT NULL COMMENT '属性分类表',PRIMARY KEY (`category_id`,`attr_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
属性表:
CREATE TABLE `sku_attribute` ( `id` int(11) NOT NULL AUTO_INCREMENT COMMENT 'ID', `name` varchar(50) DEFAULT NULL COMMENT '属性名称', `options` varchar(2000) DEFAULT NULL COMMENT '属性选项', `sort` int(11) DEFAULT NULL COMMENT '排序', PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=13 DEFAULT CHARSET=utf8;
CREATE TABLE `spu` ( `id` varchar(60) NOT NULL COMMENT '主键', `name` varchar(100) DEFAULT NULL COMMENT 'SPU 名', `intro` varchar(200) DEFAULT NULL COMMENT '简介', `brand_id` int(11) DEFAULT NULL COMMENT '品牌 ID', `category_one_id` int(20) DEFAULT NULL COMMENT '一级分类', `category_two_id` int(10) DEFAULT NULL COMMENT '二级分类', `category_three_id` int(10) DEFAULT NULL COMMENT '三级分类', `images`varchar(1000) DEFAULT NULL COMMENT '图片列表', `after_sales_service` varchar(50) DEFAULT NULL COMMENT '售后服务', `content` longtext COMMENT '介绍', `attribute_list` varchar(3000) DEFAULT NULL COMMENT '规格列表', `is_marketable` int(1) DEFAULT '0' COMMENT '是否上架,0 已下架,1 已上架', `is_delete` int(1) DEFAULT '0' COMMENT '是否删除,0:未删除,1:已删除', `status` int(1) DEFAULT '0' COMMENT '审核状态,0:未审核,1:已审核,2:审核不通过', PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `sku` ( `id` varchar(60) NOT NULL COMMENT '商品 id', `name` varchar(200) NOT NULL COMMENT 'SKU 名称', `price` int(20) NOT NULL DEFAULT '1' COMMENT '价格(分)', `num` int(10) DEFAULT '100' COMMENT '库存数量', `image` varchar(200) DEFAULT NULL COMMENT '商品图片', `images` varchar(2000) DEFAULT NULL COMMENT '商品图片列表',`create_time` datetime DEFAULT NULL COMMENT '创建时间', `update_time` datetime DEFAULT NULL COMMENT '更新时间', `spu_id` varchar(60) DEFAULT NULL COMMENT 'SPUID', `category_id` int(10) DEFAULT NULL COMMENT '类目 ID', `category_name` varchar(200) DEFAULT NULL COMMENT '类目名称', `brand_id` int(11) DEFAULT NULL COMMENT '品牌 id', `brand_name` varchar(100) DEFAULT NULL COMMENT '品牌名称', `sku_attribute` varchar(200) DEFAULT NULL COMMENT '规格', `status` int(1) DEFAULT '1' COMMENT '商品状态 1-正常,2-下架,3-删除', PRIMARY KEY (`id`), KEY `cid` (`category_id`), KEY `status` (`status`), KEY `updated` (`update_time`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='商品表';
订单详表:
CREATE TABLE `order_master` ( `order_id` int unsigned NOT NULL AUTO_INCREMENT COMMENT '订单 ID', `order_sn` bigint(20) unsigned NOT NULL COMMENT '订单编号 yyyymmddnnnnnnnn', `customer_id` int unsigned NOT NULL COMMENT '下单人 ID', `shipping_user` varchar(10) NOT NULL COMMENT '收货人姓名', `province` smallint NOT NULL COMMENT '收货人所在省', `city` smallint NOT NULL COMMENT '收货人所在市', `district` smallint NOT NULL COMMENT '收货人所在区', `address` varchar(100) NOT NULL COMMENT '收货人详细地址', `payment_method` tinyint NOT NULL COMMENT '支付方式:1 现金,2 余额,3 网银,4 支付宝,5 微信', `order_money` decimal(8,2) NOT NULL COMMENT '订单金额', `district_money` decimal(8,2) NOT NULL DEFAULT '0.00' COMMENT '优惠金额', `shipping_money` decimal(8,2) NOT NULL DEFAULT '0.00' COMMENT '运费金额', `payment_money` decimal(8,2) NOT NULL DEFAULT '0.00' COMMENT '支付金额', `shipping_comp_name` varchar(10) DEFAULT NULL COMMENT '快递公司名称', `shipping_sn` varchar(50) DEFAULT NULL COMMENT '快递单号', `create_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '下单时间',`shipping_time` datetime DEFAULT NULL COMMENT '发货时间', `pay_time` datetime DEFAULT NULL COMMENT '支付时间',`receive_time` datetime DEFAULT NULL COMMENT '收货时间', `order_status` tinyint NOT NULL DEFAULT '0' COMMENT '订单状态', `order_point` int unsigned NOT NULL DEFAULT '0' COMMENT '订单积分', `invoice_title` varchar(100) DEFAULT NULL COMMENT '发票抬头', `modified_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATECURRENT_TIMESTAMP COMMENT '最后修改时间',PRIMARY KEY (`order_id`),UNIQUE KEY `ux_ordersn` (`order_sn`)
) ENGINE=InnoDB COMMENT='订单主表';
CREATE TABLE `order_detail` ( `order_detail_id` int unsigned NOT NULL AUTO_INCREMENT COMMENT '自增主键 ID,订单详情表 ID', `order_id` int unsigned NOT NULL COMMENT '订单表 ID', `product_id` int unsigned NOT NULL COMMENT '订单商品 ID', `product_name` varchar(50) NOT NULL COMMENT '商品名称', `product_cnt` int NOT NULL DEFAULT '1' COMMENT '购买商品数量', `product_price` decimal(8,2) NOT NULL COMMENT '购买商品单价', `average_cost` decimal(8,2) NOT NULL DEFAULT '0.00' COMMENT '平均成本价格', `weight` float DEFAULT NULL COMMENT '商品重量', `fee_money` decimal(8,2) NOT NULL DEFAULT '0.00' COMMENT '优惠分摊金额', `w_id` int unsigned NOT NULL COMMENT '仓库 ID', `modified_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATECURRENT_TIMESTAMP COMMENT '最后修改时间',PRIMARY KEY (`order_detail_id`)
) ENGINE=InnoDB COMMENT='订单详情表';