网站做权重的方法,石家庄网站建设公司怎么样,网站建设 用英语,辽宁住房和建设厅网站文章目录 #x1f343;前言#x1f384;开发环境安装#x1f333;服务拆分的原则#x1f6a9;单一职责原则#x1f6a9;服务自治#x1f6a9;单向依赖 #x1f340;搭建案例介绍#x1f334;数据准备#x1f38b;工程搭建#x1f6a9;构建父子工程#x1f388;创建父… 文章目录 前言开发环境安装服务拆分的原则单一职责原则服务自治单向依赖 搭建案例介绍数据准备工程搭建构建父子工程创建父工程创建⼦项目-订单服务与商品服务完善订单服务完善商品服务 远程调用调用需求实现测试 项目存在问题⭕总结 前言
Spring Cloud 提供了⼀些可以让开发⼈员快速构建分布式服务的⼯具⽐如配置管理 服务发现,熔断智能路由等。他们可以在任何分布式环境中很好的⼯作。
简单来说Spring Cloud 就是分布式微服务架构的⼀站式解决⽅案是微服务架构落地的多种技术的集合
既然Spring Cloud是用来解决微服务所带来的问题。那我们接下来就先搭建一个简单的微服务。
本篇内容主要非为以下两点
开发环境安装项⽬搭建
开发环境安装
首先 JDK 版本的选择方面
我们选择 JDK17 选择 JDK17 的原因是因为Spring Cloud 是基于 SpringBoot 进⾏开发的, SpringBoot 3.X以下的版本, Spring官⽅已不再进⾏维护(还可以继续使⽤), SpringBoot 3.X的版本, 使⽤的JDK版本基本为JDK17. 鉴于JDK21是 2023.09⽉发布的, 很多功能还没有在⽣产环境验证, 所以选择使⽤JDK17。
数据库方面我们选择MySQL
服务拆分的原则
微服务应用开发的第一步, 就是服务拆分.拆分后才能进行各自开发”
微服务的拆分原则主要为以下三个原则 单⼀职责原则 服务⾃治 单向依赖
单一职责原则
单⼀职责原则原本是⾯向对象设计中的⼀个基本原则它指的是⼀个类应该专注于单⼀功能。不要存在多于⼀个导致类变更的原因
在微服务架构中,⼀个微服务也应该只负责⼀个功能或业务领域,每个服务应该有清晰的定义和边界,只关注⾃⼰的特定业务领域
以电商平台为例拆分为以下服务
服务自治
服务⾃治是指每个微服务都应该具备⾼度⾃治的能⼒,即每个服务要能做到独⽴开发,独⽴测试,独⽴构建,独⽴部署,独⽴运⾏.
以上⾯的电商系统为例每⼀个微服务应该有⾃⼰的存储,配置在进⾏开发,构建,部署,运⾏和测试时并不需要过多关注其他微服务的状态和数据 单向依赖
微服务之间需要做到单向依赖, 严禁循环依赖, 双向依赖 循环依赖:A - B - C -A 双向依赖: A - B, B - A 搭建案例介绍
⼀个完整的电商系统是庞⼤的搭建微服务困难较大这里我们实现一的简单的微服务其中的一部分以订单列表为例:
大致可拆分为以下两个服务 订单服务: 提供订单ID, 获取订单详细信息 商品服务: 根据商品ID, 返回商品详细信息 数据准备
-- 建cloud_order库
create database if not exists cloud_order charset utf8mb4;
-- 订单表
DROP TABLE IF EXISTS order_detail;
CREATE TABLE order_detail (id INT NOT NULL AUTO_INCREMENT COMMENT 订单id,user_id BIGINT ( 20 ) NOT NULL COMMENT ⽤⼾ID,product_id BIGINT ( 20 ) NULL COMMENT 产品id,num INT ( 10 ) NULL DEFAULT 0 COMMENT 下单数量,price BIGINT ( 20 ) NOT NULL COMMENT 实付款,delete_flag TINYINT ( 4 ) NULL DEFAULT 0,create_time DATETIME DEFAULT now(),update_time DATETIME DEFAULT now(),
PRIMARY KEY ( id )) ENGINE INNODB DEFAULT CHARACTER
SET utf8mb4 COMMENT 订单表;
-- 数据初始化
insert into order_detail (user_id,product_id,num,price)
values
(2001, 1001,1,99), (2002, 1002,1,30), (2001, 1003,1,40),
(2003, 1004,3,58), (2004, 1005,7,85), (2005, 1006,7,94);-- 建cloud_product库
create database if not exists cloud_product charset utf8mb4;
-- 产品表
DROP TABLE IF EXISTS product_detail;
CREATE TABLE product_detail (id INT NOT NULL AUTO_INCREMENT COMMENT 产品id,product_name varchar ( 128 ) NULL COMMENT 产品名称,product_price BIGINT ( 20 ) NOT NULL COMMENT 产品价格,state TINYINT ( 4 ) NULL DEFAULT 0 COMMENT 产品状态 0-有效 1-下架,create_time DATETIME DEFAULT now(),update_time DATETIME DEFAULT now(),
PRIMARY KEY ( id )) ENGINE INNODB DEFAULT CHARACTER
SET utf8mb4 COMMENT 产品表;
-- 数据初始化
insert into product_detail (id, product_name,product_price,state)
values
(1001,T恤, 101, 0), (1002, 短袖,30, 0), (1003, 短裤,44, 0),
(1004, 卫⾐,58, 0), (1005, ⻢甲,98, 0),(1006,⽻绒服, 101, 0),
(1007, 冲锋⾐,30, 0), (1008, 袜⼦,44, 0), (1009, 鞋⼦,58, 0),
(10010, ⽑⾐,98, 0)工程搭建
构建父子工程
创建父工程
创建⼀个空的Maven项⽬,删除所有代码,只保留pom.xml 目录结构如下 完善pom⽂件
使⽤properties来进⾏版本号的统⼀管理,使⽤dependencyManagement来管理依赖,声明⽗⼯程的打包⽅式为pom
?xml version1.0 encodingUTF-8?
project xmlnshttp://maven.apache.org/POM/4.0.0xmlns:xsihttp://www.w3.org/2001/XMLSchema-instancexsi:schemaLocationhttp://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsdmodelVersion4.0.0/modelVersiongroupIdorg.example/groupIdartifactIdspring_cloud/artifactIdversion1.0-SNAPSHOT/versionpackagingpom/packagingmodulesmoduleorder-service/modulemoduleproduct-service/module/modulesparentgroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-parent/artifactIdversion3.1.6/versionrelativePath/ !-- lookup parent from repository --/parentpropertiesmaven.compiler.source17/maven.compiler.sourcemaven.compiler.target17/maven.compiler.targetjava.version17/java.versionmybatis.version3.0.3/mybatis.versionmysql.version8.0.33/mysql.versionspring-cloud.version2022.0.3/spring-cloud.version/propertiesdependenciesdependencygroupIdorg.projectlombok/groupIdartifactIdlombok/artifactIdoptionaltrue/optional/dependency/dependenciesdependencyManagementdependenciesdependencygroupIdorg.springframework.cloud/groupIdartifactIdspring-cloud-dependencies/artifactIdversion${spring-cloud.version}/versiontypepom/typescopeimport/scope/dependencydependencygroupIdorg.mybatis.spring.boot/groupIdartifactIdmybatis-spring-boot-starter/artifactIdversion${mybatis.version}/version/dependencydependencygroupIdcom.mysql/groupIdartifactIdmysql-connector-j/artifactIdversion${mysql.version}/version/dependencydependencygroupIdorg.mybatis.spring.boot/groupIdartifactIdmybatis-spring-boot-starter-test/artifactIdversion${mybatis.version}/versionscopetest/scope/dependency/dependencies/dependencyManagement/project这里有两个标签DependencyManagement 和 Dependencies作用如下 dependencies 将所依赖的jar直接加到项⽬中。⼦项⽬也会继承该依赖. dependencyManagement只是声明依赖,并不实现Jar包引⼊。如果⼦项⽬需要⽤到相关依赖,需要显式声明。如果⼦项⽬没有指定具体版本,会从⽗项⽬中读取version。如果⼦项⽬中指定了版本号就会使⽤⼦项⽬中指定的jar版本。此外⽗⼯程的打包⽅式应该是pom不是jar这⾥需要⼿动使⽤packaging 来声明 这里需要注意的时由于后续使用的Spring Cloud 是基于SpringBoot搭建的,所以Spring Cloud 版本与SpringBoot版本有关
这里使用的咱们项⽬中使⽤的SpringBoot 版本为 3.1.6, 对应的Spring Cloud版本应该为2022.0.x。各位也可以根据自己的版本进行选择。
创建⼦项目-订单服务与商品服务
以下为订单服务的创建过程商品服务与之一样名字不同罢了 声明项⽬依赖和项⽬构建插件
propertiesmaven.compiler.source17/maven.compiler.sourcemaven.compiler.target17/maven.compiler.targetproject.build.sourceEncodingUTF-8/project.build.sourceEncoding
/properties
dependencies
dependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-web/artifactId
/dependencydependencygroupIdcom.mysql/groupIdartifactIdmysql-connector-j/artifactId/dependency!--mybatis--dependencygroupIdorg.mybatis.spring.boot/groupIdartifactIdmybatis-spring-boot-starter/artifactId/dependency
/dependencies
buildpluginsplugingroupIdorg.springframework.boot/groupIdartifactIdspring-boot-maven-plugin/artifactId/plugin/plugins
/build完善订单服务 启动类
SpringBootApplication
public class OrderServiceApplication {public static void main(String[] args) {SpringApplication.run(OrderServiceApplication.class,args);}
}配置文件
server:port: 9998
spring:datasource:url: jdbc:mysql://127.0.0.1:3306/cloud_order?characterEncodingutf8useSSLfalseusername: 用户password: 密码driver-class-name: com.mysql.cj.jdbc.Driver
mybatis:configuration: # 配置打印 MyBatis⽇志log-impl: org.apache.ibatis.logging.stdout.StdOutImplmap-underscore-to-camel-case: true #配置驼峰⾃动转换实体类
Data
public class OrderInfo {private int id;private int userId;private int productId;private int num;private long price;private boolean deleteFlag;private Date createTime;private Date update_time;
}mapper
Mapper
public interface OrderMapper {Select(select * from order_detail where id#{id})OrderInfo selectAll(int id);
}service
Service
public class OrderService {Autowiredprivate OrderMapper orderMapper;public OrderInfo selectAll(Integer userid) {OrderInfo orderInfo orderMapper.selectAll(userid);return orderInfo;}
}controller
RestController
RequestMapping(/order)
public class OrderController {AutowiredOrderService orderService;RequestMapping(/{id})public OrderInfo selectAll(PathVariable(id) int id) {return orderService.selectAll(id);}
}测试访问http://127.0.0.1:9998/order/1
即可看到以下界面
完善商品服务 启动类
SpringBootApplication
public class ProductServiceApplication {public static void main(String[] args) {SpringApplication.run(ProductServiceApplication.class,args);}
}配置文件
server:port: 9999
spring:datasource:url: jdbc:mysql://127.0.0.1:3306/cloud_product?characterEncodingutf8useSSLfalseusername: 用户password: 密码driver-class-name: com.mysql.cj.jdbc.Driver
mybatis:configuration: # 配置打印 MyBatis⽇志log-impl: org.apache.ibatis.logging.stdout.StdOutImplmap-underscore-to-camel-case: true #配置驼峰⾃动转换实体类
Data
public class ProductInfo {private int id;private String productName;private long productPrice;private boolean state;private Date createTime;private Date updateTime;
}mapper
Mapper
public interface ProductMapper {Select(select * from product_detail where id#{id})ProductInfo selectById(int id);
}service
Service
public class ProductService {AutowiredProductMapper productMapper;public ProductInfo selectById(int id) {return productMapper.selectById(id);}
}controller
RestController
RequestMapping(/product)
public class ProductController {AutowiredProductService productService;RequestMapping(/{id})public ProductInfo selectById(PathVariable(id) int id) {ProductInfo productInfo productService.selectById(id);return productInfo;}
}测试http://127.0.0.1:9999/product/1001 页面返回结果如下
远程调用
调用需求
我们一般有如下需求
根据订单查询订单信息时,根据订单⾥产品ID,获取产品的详细信息 意思是我们希望访问订单页面时也可以访问到商品服务。
实现
实现思路order-service服务向product-service服务发送⼀个http请求把得到的返回结果,和订单结果融合在⼀起,返回给调⽤⽅。
实现⽅式采⽤Spring提供的RestTemplate
首先因为我们需要返回商品的信息所以这里我们需要对我们的实体类进行修改修改如下
其次我们创建一个config文件在其文件下进行以下配置
Configuration
public class OrderConfig {Beanpublic RestTemplate restTemplate() {return new RestTemplate();}
}接下来我们对我们原先的 service 类里面的代码进行修改修改如下
Service
public class OrderService {Autowiredprivate OrderMapper orderMapper;Autowiredprivate RestTemplate restTemplate;public OrderInfo selectAll(Integer userid) {OrderInfo orderInfo orderMapper.selectAll(userid);String url http://127.0.0.1:9999/product/ orderInfo.getProductId();restTemplate.getForObject(url, ProductInfo.class);ProductInfo productInfo restTemplate.getForObject(url,ProductInfo.class);orderInfo.setProductInfo(productInfo);return orderInfo;}
}测试
启动商品服务与订单服务
访问http://127.0.0.1:9998/order/1
则会出现以下界面
项目存在问题
远程调⽤时,URL的IP和端⼝号是写死的如果更换IP需要修改代码 。调⽤⽅如何可以不依赖服务提供⽅的IP?多机部署如何分摊压⼒?远程调⽤时URL⾮常容易写错⽽且复⽤性不⾼如何优雅的实现远程调⽤所有的服务都可以调⽤该接是否有⻛险?… 除此之外,微服务架构还⾯临很多问题,而Spring Cloud 来就是用来解决这些问题
具体如何解决后续文章再进行一一介绍
⭕总结
关于《【Spring Cloud】微服务的简单搭建》就讲解到这儿感谢大家的支持欢迎各位留言交流以及批评指正如果文章对您有帮助或者觉得作者写的还不错可以点一下关注点赞收藏支持一下