Java SpringBoot整合SpringCloud
作者:Tttori 发布时间:2022-11-11 15:07:46
目录
1. SpringCloud特点
2. 分布式系统的三个指标CAP
3. Eureka
4. SpringCloud Demo
4.1 registry
4.2 api
4.3 provider
4.4 consumer
4.5 POSTMAN一下
1. SpringCloud特点
SpringCloud
专注于为典型的用例和扩展机制提供良好的开箱即用体验,以涵盖其他情况:
分布式/版本化配置
服务注册和发现
Eureka
路由
Zuul
服务到服务的呼叫
负载均衡
Ribbon
断路器
Hystrix
分布式消息传递
2. 分布式系统的三个指标CAP
在介绍SpringCloud
默认使用的注册中心前,先介绍分布式系统的三个指标,分别是:
Consistency:
一致性,在分布式系统中,更新操作执行成功后所有的用户的读操作必须返回最新值;client写入,server同步至整个系统;Availability:
可用性,只要收到用户的请求,在一定的时间内服务器就必须给出回应,回应的结果可以是成功或是失败;Partition tolerance:
分区容错,即区间通信可能失败,在网络中断,消息丢失的情况下,仍对外提供服务;一般无法避免,可以认为CAP中的P总是成立
CAP
定律说的是,在一个分布式计算机系统中,一致性C,可用性A,分区容错性P这三种保证无法同时得到满足,最多满足两个:
放弃P:
为了避免分区容错性问题的发生,一种做法是将所有与事务相关的数据都放在一台服务器上,虽然不能保证100%系统不会出错,但是不会碰到由分区带来的负面效果,这样的做法会严重影响系统的扩展性。
放弃A:
放弃可用性,一旦遇到分区容错故障,受到影响的服务器需要等待一定的时间,因此会导致在等待期间系统无法对外提供服务。
放弃C:
这儿说的放弃一致性,并不是完全放弃数据的一致性,而是放弃数据的强一致性,而保留数据的最终一致性。以网络购物为例,对只剩下一件库存的商品,如果同时接受到了两份订单,那么较晚的订单将被告知商品告罄。
文中部分CAP理论摘自: https://www.cnblogs.com/hxsyl/p/4381980.html
3. Eureka
基本介绍:
Eureka
是SpringCloud
官方推荐用于服务注册和发现,一个基于REST的服务
SpringBoot
实现了Netflix OSS
的集成,使用Eureka
的原因之一是因为其可以利用Spring Cloud Netflix
的其他组件:智能路由(Zuul)、客户端负载均衡(Ribbon
)等
基本组成:
Eureka
由多个Instance
(服务实例)组成,分为Eureka Server
和Eureka Client
其中Eureka Client
又可细分为:Service Provider、Service Consumer
Eureka Server
:服务端,提供服务的注册和发现;Eureka Client
:客户端
Service Provider
:服务提供方,将自身服务注册到Eureka,让消费方找到Service Consumer
:服务消费方,从Eureka获取注册服务列表,从而消费服务
Eureka和Zookeeper:
1)由CAP理论的角度来看
Zookeeper
:ZK保证CP,突出强一致性,但无法保证每次访问服务可用性,比如ZK会出现这样一种情况:当master节点因为网络故障与其他节点失去联系时,剩余节点会重新进行leader选举,在ZK选举leader期间整个ZK集群都是不可用的,这就导致了在选举期间注册服务瘫痪。在云部署的环境下,因网络问题使得ZK集群失去master节点是较大概率会发生的事儿,虽然服务最终会恢复,但是漫长的选举时间导致的注册长期不可用是难以容忍的。
Eureka
:Eureka保证AP,Eureka在设计时就优先保证可用性。对于Eureka中的节点,每个节点都是平等的,几个节点挂掉也不会影响正常节点的工作,剩余的节点依然可以提供注册和查询服务。但Eureka不保证强一致性,即查到的信息可能不是最新的。此外Eureka还有一种自我保护机制,如果在15分钟内超过85%的节点都没有正常的心跳,那么Eureka就会认为客户端和注册中心出现了网络故障,但会保证当前节点依然可用,不会像ZK导致整个注册服务瘫痪。
2)由节点分工的角度来看
Zookeeper
:ZK集群中节点分为三类,承担不同的任务
Leader
:事务请求唯一的调度者和处理者(除了查询请求)Follower
:处理非事务请求,参与Leader选举投票Observer:处理非事务请求,但不参与Leader选举投票
Eureka
:在Eureka
集群中每个节点都是平等的,每个节点扮演相同的角色,它们通过相互注册的方式来感知对方的存在,当由注册消息时,它们会同步给集群内的其他节点
4. SpringCloud Demo
Demo整体结构(父子项目)
api
:Bean、DTO、POJO等以及Service接口controller
:服务消费方,前端交互provider
:服务提供方,服务实现registry
:服务注册中心
4.1 registry
1)pom.xml
关键点在于导入eureka服务端依赖
以及SpringCloud
依赖
<dependencies>
<!-- https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-starter-netflix-eureka-server -->
<!-- eureka服务端 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
<version>2.2.5.RELEASE</version>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Hoxton.SR6</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
2)application.properties
进行Eureka服务端的相关配置
spring.application.name=SpringCloudDemoRegistry
# server端口,自己喜欢
server.port=8888
# Eureka Server服务url以及默认zone,结尾必须eureka
eureka.client.service-url.defaultZone= http://127.0.0.1:8888/eureka/
# eureka的自我保护机制,k8s环境下建议false
eureka.server.enable-self-preservation=false
# false表示自己端就是注册中心,我的功能就是维护服务实例,不需要从server获取注册的服务信息
eureka.client.fetch-registry=false
# false表示不将自己注册到Eureka Server
eureka.client.register-with-eureka=false
3)EurekaregistryApplication
使用@EnableEurekaServer
激活相关配置,使registry
模块作为注册中心Server
@EnableEurekaServer //声明为注册中心服务端
@SpringBootApplication
public class EurekaregistryApplication {
public static void main(String[] args) {
SpringApplication.run(EurekaregistryApplication.class, args);
}
}
4.2 api
1)entity
实体类以部门和用户信息为例,由于演示使用了Lombok
省点代码,用于实现基本的CRUD
Department.class
@Data
@ToString
@NoArgsConstructor
@AllArgsConstructor
public class Department {
private Long id;
private Integer dId;
private String dName;
private Date updateTime;
}
UserInfo.class
@Data
@ToString
@NoArgsConstructor
@AllArgsConstructor
public class UserInfo {
private Long id;
private Integer uId;
private Integer dId;
private String uName;
private String uPhone;
@Email(message = "非法邮件格式") //Validator格式校验
private String uEmail;
private String uAddress;
private Date updateTime;
private Department department;
}
2)UserService
UserService
为服务接口,声明需要提供和消费的方法,写了几个简单查询
public interface UserService {
/**
* 判断用户是否存在,0为不存在,返回值与uId相等则存在
* @param uId
* @return
*/
Integer userExist(Integer uId);
/**
* 获取用户个人基本信息
* @param uId
* @return
*/
UserInfo getUserInfo(Integer uId);
/**
* 获取用户个人详情信息
* @param uId
* @return
*/
UserInfo getUserDetailsInfo(Integer uId);
}
4.3 provider
1)pom.xml
关键点是引入eureka客户端依赖
、openfeign依赖
、SpringCloud
依赖
<dependencies>
<!-- Springboot的依赖省略... -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Hoxton.SR6</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
2)application.properties
配置Eureka
、Mybatis
以及DataSource
数据源等信息
spring.application.name=SpringCloudDemoProvider
# Server端口
server.port=9999
# Eureka服务url
eureka.client.service-url.defaultZone= http://127.0.0.1:8888/eureka/
eureka.client.register-with-eureka=true
eureka.client.fetch-registry=true
# Mybatis
mybatis.mapper-locations= classpath:com.maziyao.provider.mapper/*.xml
mybatis.type-aliases-package= com.maziyao.common.entity
# DataSource数据源配置
spring.datasource.type=com.zaxxer.hikari.HikariDataSource
# DataSource
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/boot-demo?serverTimezone=UTC
spring.datasource.username=root
spring.datasource.password=root
3)EurekaproviderApplication
provider
启动类使用@EnableEurekaClient
声明为EurekaClient
客户端,作为ServiceProvider
@EnableEurekaClient
@SpringBootApplication
@EnableAspectJAutoProxy
@MapperScan("com.maziyao.provider.mapper")
@ComponentScan(basePackages = {
"com.maziyao.provider.rest",
"com.maziyao.provider.redis",
"com.maziyao.provider.service",
"com.maziyao.provider.config"
})
public class EurekaproviderApplication {
public static void main(String[] args) {
SpringApplication.run(EurekaproviderApplication.class, args);
}
}
4)service
UserServiceImpl
作为UserService
接口实现类,@Service
用于标注 业务层 组件
自动注入mapper
层的mapper
接口并调用,mapper的SQL语句下面就略了,很简单
需要注意的是,对于 数据访问层 组件mapper
,使用@Repository
进行标注
@Service("userService")
public class UserServiceImpl implements UserService {
@Autowired
private UserMapper userMapper;
@Override
public Integer userExist(Integer uId) {
return userMapper.userExist(uId);
}
@Override
public UserInfo getUserInfo(Integer uId) {
return userMapper.getUserInfo(uId);
}
@Override
public UserInfo getUserDetailsInfo(Integer uId) {
return userMapper.getUserDetailsInfo(uId);
}
}
5)rest
重点是rest包下的UserServer
,要知道Eureka是一个基于REST的服务
使用@RestController
标注并声明为userServer
,这个是SpringBoot
注解,用于标注 控制层 组件
@RestController("userServer")
public class UserServer {
public static final Logger logger = LoggerFactory.getLogger(UserServer.class);
@Autowired
private UserService userService;
@ResponseBody
@RequestMapping(value = "/exist",method = RequestMethod.GET)
public Integer existUserByUid(@RequestParam("uId")Integer uId){
return userService.userExist(uId);
}
@ResponseBody
@RequestMapping(value = "/userInfo",method = RequestMethod.GET)
public UserInfo getUserInfo(@RequestParam("uId")Integer uId){
return userService.getUserInfo(uId);
}
@ResponseBody
@RequestMapping(value="/userDetailsInfo",method = RequestMethod.GET)
public UserInfo getUserDetailsInfo(@RequestParam("uId")Integer uId){
return userService.getUserDetailsInfo(uId);
}
}
4.4 consumer
1)pom.xml
在Controller
的pom.xml
中也需要导入EurekaClient
的依赖,对于Provider
和Controller
都为Client
<dependencies>
<!-- SpringBoot依赖省略... -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
<version>2.2.5.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
<version>2.2.5.RELEASE</version>
</dependency>
</dependencies>
2)application.properties
在application.properties
中配置Eureka
相关信息
spring.application.name=springCloudDemoController
# Server端口
server.port=8899
# 注册中心url
eureka.client.service-url.defaultZone= http://127.0.0.1:8888/eureka/
eureka.client.register-with-eureka=true
eureka.client.fetch-registry=true
3)EurekacontrollerApplication
与Provider
的启动类一致,声明启动类为Eureka
的客户端
并使用@EnableFeignClients
开启Feign
,声明性的web服务客户端
@EnableEurekaClient
@EnableFeignClients
@SpringBootApplication
@EnableAspectJAutoProxy
@ComponentScan({
"com.maziyao.controller.config",
"com.maziyao.controller.controller",
"com.maziyao.controller.rest"
})
public class EurekacontrollerApplication {
public static void main(String[] args) {
SpringApplication.run(EurekacontrollerApplication.class, args);
}
}
4)rest
controller
作为前端交互层,即控制层,此处UserClient
声明调用方法
使用@FeignClient
声明服务提供方在application.properties
中配置的spring.application.name
以及绑定服务提供方对应rest
包下的UserServer
类的@RestController("userServer")
@FeignClient(name = "springCloudDemoProvider",contextId = "userServer")
public interface UserClient {
@ResponseBody
@RequestMapping(value = "/exist",method = RequestMethod.GET)
public Integer existUserByUid(@RequestParam("uId")Integer uId);
@ResponseBody
@RequestMapping(value = "/userInfo",method = RequestMethod.GET)
public UserInfo getUserInfo(@RequestParam("uId")Integer uId);
@ResponseBody
@RequestMapping(value="/userDetailsInfo",method = RequestMethod.GET)
public UserInfo getUserDetailsInfo(@RequestParam("uId")Integer uId);
}
5)UserController
控制层,使用@RestController
标注,并注入UserClien
t进行调用
@RestController
public class UserController {
private static final Logger logger = LoggerFactory.getLogger(UserController.class);
@Autowired
private UserClient userClient;
@ResponseBody
@RequestMapping(value = "/exist",method = RequestMethod.GET)
public Integer existUserByUid(@RequestParam("uId") Integer uId){
return userClient.existUserByUid(uId);
}
@ResponseBody
@RequestMapping(value = "/userInfo",method = RequestMethod.GET)
public UserInfo getUserInfoByUid(@RequestParam("uId")Integer uId){
return userClient.getUserInfo(uId);
}
@ResponseBody
@RequestMapping(value = "/userDetailsInfo",method = RequestMethod.GET)
public UserInfo getUserDetailsInfoByUid(@RequestParam("uId")Integer uId){
return userClient.getUserDetailsInfo(uId);
}
}
4.5 POSTMAN一下
注意:最后记得mvn install
,需要先将registry
运行起来,再分别运行provider
和controller
启动registry:
启动provider:
启动consumer:
result:
来源:https://www.cnblogs.com/torima/p/15277106.html


猜你喜欢
- 工厂模式和简单工厂有什么区别。废话不多说,对比第一篇例子应该很清楚能看出来。优点: 工厂模式弥补了简单工厂模式中违背开放-封闭原则,又保持了
- 尽管我们通常认为通过JAVA的反射机制来访问其它类的私有字段和私有方法是可行的,其实并没有那么困难。 注释:只有在单独的JAVA程序中运行该
- Home键(小房子键)在键盘上映射的就是home键,这倒是很好记。Menu键用于打开菜单的按键,在键盘上映射的是F2键,PgUp键同样可以。
- 一、简介:开发中在用户注册或找回密码之类的功能,经常会遇到获取短信验证码,获取验证码后需要等待1分钟倒计时,这段时间是不能再次发送短信请求的
- 通过本文你可以用非常简短的代码替代业务逻辑中的判null校验,并且很容易的在出现空指针的时候进行打日志或其他操作。注:如果对Java8新特性
- java io操作中通常采用BufferedReader,BufferedInputStream等带缓冲的IO类处理大文件,不过java n
- 实例如下:static bool CheckPowerOfTwo(ulong num){ return num > 0 &
- 1.首先,需要指定获取的文件夹,以及获取文件的文件名;文件夹:strLocalPath = System.Windows.Forms.App
- 刚学完JDBC不久,做了一个简单的学生管理系统,可能还有不完善的地方,望各路大神见谅。废话不多说,我先贴个图让大家让大家瞅瞅,觉得是你想要的
- 1、在启动线程时,为什么要通过调用方法start执行方法run,而不能直接执行方法run?调用方法start执行方法run,才是多线程的工作
- 本文实例讲述了Java使用DateFormatter格式化日期时间的方法。分享给大家供大家参考,具体如下:Java版本:1.8开始impor
- 本文为大家分享了Unity3D实现虚拟按钮控制人物移动的具体代码,供大家参考,具体内容如下创建Image的UI组件,在Image下新建一个B
- 很多童鞋反应在吧项目导入到eclipse(myeclipse)时中文会有乱码,修改了编码格式后还是乱码,这里给大家介绍一下关于中文乱码时修改
- 本文实例讲述了Android开发中MotionEvent坐标获取方法。分享给大家供大家参考,具体如下:Android MotionEvent
- 下面是一个邮件接收的工具类,有点长!!!public class ReciveMail { private MimeMessage msg
- Android 实现记住用户名和密码的功能是通过SharedPreference 存储来实现的。创建一个复选按钮,通过按钮的否选取来进行事件
- Socket,又称为套接字,Socket是计算机网络通信的基本的技术之一。如今大多数基于网络的软件,如浏览器,即时通讯工具甚至是P2P下载都
- 本文实例为大家分享了ActionBar下拉式导航的实现代码,供大家参考,具体内容如下利用Actionbar同样可以很轻松的实现下拉式的导航方
- 目录一、首先模型本身需要特殊处理二、编写Shader三、讲解先上图看看效果:下面详细分享一下制作步骤吧:一、首先模型本身需要特殊处理二、编写
- SpringBoot项目当中支持的三类配置文件:application.propertiesapplication.ymlapplicati