SpringCloud-环境和工程搭建
前言
JDK用17,MySQL用8.0
微服务就是微小的服务
一个微服务只做一个事情
基本概念
打开官网
spring
springcloud就是给我们提供工具,方便我们来弄微服务
springcloud是分布式微服务架构的一站式解决方案
Distributed/versioned configuration 分布式版本配置
• Service registration and discovery 服务注册和发现
• Routing 路由
• Service-to-service calls 服务调⽤
• Load balancing 负载均衡
• Circuit Breakers 断路器
• Distributed messaging 分布式消息
这个是它的版本
这里就是使用springcloud的版本要和下面组件的版本一一对应,不然可能会出错
这个是springcloud和springboot版本的对应关系
springcloud下有很多的组件
springcloud实现方案
在SpringCloud的规范下,有很多实现,其中最为出名的是
SpringCloudNetflix
SpringCloudAlibaba
Spring Cloud Alibaba 是什么
环境安装和配置
jdk安装
1.JDK17,因为旧的版本不会维护,长期维护版本:jdk8,17,21
2.MySQL
下载jdk
jdk17
我们安装windows的
然后就是配置环境变量,编辑系统环境变量
配置JAVA_HOME为安装目录
然后还有配置path
把java_home配置到bin下
然后就是验证一下
这样就成功了
然后就是Linux安装jdk我们已经安装过了
sudo apt update
sudo apt install openjdk-17-jdk
java -version
卸载jdk
#检查安装的哪个jdk
dpkg --list | grep -i jdk
#移除openjdk包
apt-get purge openjdk-*
#卸载openjdk相关包
apt-get purge icedtea-* openjdk-*
#检查删干净没有
dpkg --list | grep -i jdk
MySQL安装
#查找
apt list | grep "mysql-server"
安装最后一个
apt install mysql-server
sudo system status mysql
查看状态
MySQL安全脚本设置
sudo mysql_secure_installation
一直敲Y就可以了
sudo mysql
然后输入修改密码的sql语句
alter user ‘root’@‘localhost’ identified with mysql_native_password by ‘密码’
下次登录就这样
mysql -p
密码
就可以链接
sysytem enable mysql开机启动
反正原来已经安装过了
grep “password” /var/log/mysql.log
这个可以查看默认密码
mysql -uroot -p
环境与工程搭建
服务拆分
- 单⼀职责原则
单⼀职责原则原本是⾯向对象设计中的⼀个基本原则,它指的是⼀个类应该专注于单⼀功能.不要存在多于⼀个导致类变更的原因.
在微服务架构中,⼀个微服务也应该只负责⼀个功能或业务领域,每个服务应该有清晰的定义和边界,只关注⾃⼰的特定业务领域. - 服务⾃治
服务⾃治是指每个微服务都应该具备⾼度⾃治的能⼒,即每个服务要能做到独⽴开发,独⽴测试,独⽴构
建,独⽴部署,独⽴运⾏.
以上⾯的电商系统为例,每⼀个微服务应该有⾃⼰的存储,配置,在进⾏开发,构建,部署,运⾏和测试
时,并不需要过多关注其他微服务的状态和数据
3.单向依赖
数据准备
每个服务都应该具有自己独立的数据库
我们有两个服务,一个是订单服务,一个是商品服务
-- 订单服务
-- 建库
create database if not exists cloud_order charset utf8mb4;
use cloud_order;
-- 订单表
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);
-- 产品服务
create database if not exists cloud_product charset utf8mb4;
-- 产品表
use cloud_product;
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);
这样我们就在本地创建好了两个服务的两个数据库了
工程搭建
springcloud的学习与项目的创建方式无关
所以我们可以采用springboot的方式—》一个窗口显示一个项目–》切换不同的服务不方便
或者父子工程的方式搭建—》一个父项目,一个子项目
先创建一个父工程
创建一个普通的maven项目
然后就是丰富pom文件
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.1.6</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<properties>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<java.version>17</java.version>
<mybatis.version>3.0.3</mybatis.version>
<mysql.version>8.0.33</mysql.version>
<spring-cloud.version>2022.0.3</spring-cloud.version>
</properties>
<dependencies>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>${mybatis.version}</version>
</dependency>
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
<version>${mysql.version}</version>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter-test</artifactId>
<version>${mybatis.version}</version>
<scope>test</scope>
</dependency>
</dependencies>
</dependencyManagement>
然后就是复制到pom文件中去
删掉这个,因为已经有了
然后就是刷新Maven
我们这里爆红应该是idea的显示问题
dependencyManagement只是声明jar包,但是并没有引入jar包,给子项目使用
如果子项目要用这些声明的东西的话。只需要加groupid和artifactid就可以了,不用写版本号了,子项目也可以自己指定版本号
没有dependencyManagement的dependencies是直接引入到项目中,并且被子项目继承
还是就是我们这里的父项目要说明打包方式为pom
现在开始创建子项目
看的出来这里还有父项目的指定
这样就创建好了子项目
再来一个
然后我们的父项目还多了一个moudules
订单服务
我们先完善订单服务的pom文件
加入
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
</dependency>
<!--mybatis-->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
<includes>
<include>**/**</include>
</includes>
</resource>
</resources>
</build>
我们上一节就说好了,子项目引入父项目声明好的,就不用写版本号了
我们在使用springboot开发的时候,不用写版本号也是因为父项目已经声明好了
这个是用来打包的
然后就是服务子项目也是这样
这些子项目都是springboot项目
然后我们给每个项目分别写好启动类,先写订单服务的
然后是写配置文件
然后就是写服务了
因为我们父项目引入了lombok,所以子项目也可以使用data注解
然后写数据库的实现mappperr
然后写service
然后就是controller
然后就是启动访问了
这样就成功了
商品服务
然后就是运行
注意两个不同的子项目都是可以一起运行的
远程调用
两个服务之间的交互怎么搞
就是根据订单服务如何得到商品服务
所以我们希望在订单里面要有一些商品的信息
可以通过http的访问,从商品服务获取订单服务的信息
怎么加载进来呢
方法
我们用第四个方法RestTemplate
RestTemplate是第三方的类,我们要用@Bean来创建这个对象
不能用什么Service注解来交给spring来管理了
只能用@Bean来交给spring来管理了
这样写出来的就是交给spring来管理的,不然普普通通写的就不是交给spring管理的
然后再service里面使用这个类
这样写就可以了
我们先启动商品服务
然后启动订单服务
这样就成功了
RestTemplate 是从Spring3.0开始⽀持的⼀个HTTP请求⼯具,它是⼀个同步的RESTAPI客⼾端,提供了常⻅的REST请求⽅案的模版
REST(Representational State Transfer), 表现层资源状态转移.
REST是由HTTP的主要设计者RoyFielding博⼠在2000年他的博⼠论⽂中提出来的⼀种软件架构⻛格.
REST是⼀种设计⻛格,并没有⼀个明确的标准.满⾜这种设计⻛格的程序或接⼝我们称之为RESTful(从单词字⾯来看就是⼀个形容词).所以RESTfulAPI就是满⾜REST架构⻛格的接⼝.
RESTful ⻛格⼤致有以下⼏个主要特征:
- 资源:资源可以是⼀个图⽚,⾳频,视频或者JSON格式等⽹络上的⼀个实体,除了⼀些⼆进制的资源
外普通的⽂本资源更多以JSON为载体、⾯向⽤⼾的⼀组数据(通常从数据库中查询⽽得到) - 统⼀接⼝:对资源的操作.⽐如获取,创建,修改和删除.这些操作正好对应HTTP协议提供的GET、
POST、PUT和DELETE⽅法.换⾔⽽知,如果使⽤RESTful⻛格的接⼝,从接⼝上你可能只能定位其
资源,但是⽆法知晓它具体进⾏了什么操作,需要具体了解其发⽣了什么操作动作要从其HTTP请
求⽅法类型上进⾏判断
⽐如同⼀个的URL:
GET/blog/{blogId}:查询博客
DELETE/blog/{blogId}:删除博客
这些内容都是通过HTTP协议来呈现的.所以RESTful是基于HTTP协议的.
RestTemplate 是Spring提供,封装HTTP调⽤,并强制使⽤RESTful⻛格.它会处理HTTP连接和关闭,
只需要使⽤者提供资源的地址和参数即可
RESTful API 缺点:
- 操作⽅式繁琐,RESTfulAPI通常根据GET,POST,PUT,DELETE来区分对资源的操作动作.但是HTTPMethod并不可直接⻅到,需要通过抓包等⼯具才能观察.如果把动作放在URL上反⽽更加直观,更利于团队的理解和交流.
- ⼀些浏览器对GET,POST之外的请求⽀持不太友好,需要额外处理.
- 过分强调资源.⽽实际业务需求可能⽐较复杂,并不能单纯使⽤增删改查就能满⾜需求,强⾏使⽤RESTful API会增加开发难度和成本.
项⽬存在问题
远程调⽤时,URL的IP和端⼝号是写死的(http://127.0.0.1:9090/product/),如果更换IP,需要修改代码
调⽤⽅如何可以不依赖服务提供⽅的IP?
多机部署,如何分摊压⼒?
远程调⽤时,URL⾮常容易写错,⽽且复⽤性不⾼,如何优雅的实现远程调⽤
所有的服务都可以调⽤该接⼝,是否有⻛险?
…
除此之外,微服务架构还⾯临很多问题, 接下来我们学习如何使⽤SpringCloud来解决这些问题
总结
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.kler.cn/a/612998.html 如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!