Spring Cloud学习笔记(一)

系统架构

演变过程:

集中式架构—垂直差分—分布式服务—服务治理(SOA)—微服务架构

分布式服务

将核心业务抽取出来,形成独立服务,各服务模块间可进行调用,有利于提高业务复用和整合,提高代码复用。
缺点:但是使系统间的耦合变高,调用关系复杂,难以维护。
在这里插入图片描述

服务治理(SOA)

当服务越来越多时,各服务间的调用关系复杂,一个服务代码的修改将会影响到其他服务(服务接口地址等),其他服务也得做出相应修改,因此需要一个调度中心,所有服务在调度中心进行注册,需要调用时也在调度中心调用其他服务,调度中心基于访问压力实时管理集群容量,提高集群利用率。
用于提高机器利用率的资源调度和治理中心是该架构的关键。
服务治理要做什么?

  • 服务注册中心,实现服务自动注册和发现,无需人为记录服务地址
  • 服务自动订阅,服务列表自动推送,服务调用透明化,无需关心依赖关系
  • 动态监控服务状态监控报告,人为控制服务状态

缺点

  • 服务间会有依赖关系,一旦某个环节出错会影响较大
  • 服务关系复杂,运维、测试部署困难,不符合DevOps思想
    在这里插入图片描述
微服务

微服务特点

  • 职责单一:每一个服务都对应唯一的业务能力,做到单一职责
  • 微:服务拆分力度很小,
  • 面向服务:每个服务对外提供服务接口API,与服务实现技术无关,与平台和语言无关,只需Rest接口
  • 自治:服务间互相独立,互不干扰
  • 前后端分离:分离开发,统一提供Rest接口
  • 数据库分离:每个服务使用自己的数据源
  • 独立部署:每个服务都是独立的组件,可复用,可替换,降低耦合,易维护
    在这里插入图片描述
    在这里插入图片描述

Spring Cloud

SpringCloud将现在非常流行的一些技术整合到一起,实现了诸如:配置管理,服务发现,智能路由,负载均衡,熔断器,控制总线,集群状态等等功能。其主要涉及的组件包括:

  • Eureka:注册中心
  • Zuul:服务网关
  • Ribbon:负载均衡
  • Feign:服务调用
  • Hystix:熔断器

微服务场景模拟

在这里插入图片描述

  • Eureka:就是服务注册中心(可以是一个集群),对外暴露自己的地址
  • 提供者:启动后向Eureka注册自己信息(地址,提供什么服务)
  • 消费者:向Eureka订阅服务,Eureka会将对应服务的所有提供者地址列表发送给消费者,并且定期更新
  • 心跳(续约):提供者定期通过http方式向Eureka刷新自己的状态

Eureka注册中心

创建spring boot应用,勾选Eureka Server
在这里插入图片描述
application.yml配置

server:
  port: 10086 # 端口
spring:
  application:
    name: eureka-server # 应用名称,会在Eureka中显示
eureka:
  client:
    register-with-eureka: false # 是否注册自己的信息到EurekaServer,默认是true
    fetch-registry: false # 是否拉取其它服务的信息,默认是true
    service-url: # EurekaServer的地址,现在是自己的地址,如果是集群,需要加上其它Server的地址。
      defaultZone: http://127.0.0.1:${server.port}/eureka

启动类添加@EnableEurekaServer注解

@SpringBootApplication
@EnableEurekaServer
public class EurekaServiceApplication {

	public static void main(String[] args) {
		SpringApplication.run(EurekaServiceApplication.class, args);
	}

}

完成Eureka配置,访问http://127.0.0.1:10086就能看到Eureka信息

服务提供者

服务提供者查询数据库信息
pom.xml文件添加配置

	<properties>
		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
		<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
		<java.version>1.8</java.version>
	</properties>
	
	<dependencyManagement>
	    <dependencies>
	        <dependency>
	            <groupId>org.springframework.cloud</groupId>
	            <artifactId>spring-cloud-dependencies</artifactId>
	            <version>Greenwich.SR1</version>
	            <type>pom</type>
	            <scope>import</scope>
	        </dependency>
	    </dependencies>
	</dependencyManagement>

	<dependencies>
		<dependency>
		    <groupId>org.springframework.cloud</groupId>
		    <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-jdbc</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>
		<dependency>
			<groupId>org.mybatis.spring.boot</groupId>
			<artifactId>mybatis-spring-boot-starter</artifactId>
			<version>2.0.1</version>
		</dependency>

		<dependency>
			<groupId>mysql</groupId>
			<artifactId>mysql-connector-java</artifactId>
			<scope>runtime</scope>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-test</artifactId>
			<scope>test</scope>
		</dependency>
		<dependency>
			<groupId>tk.mybatis</groupId>
			<artifactId>mapper-spring-boot-starter</artifactId>
			<version>2.0.2</version>
		</dependency>
		<dependency>
			<groupId>org.projectlombok</groupId>
			<artifactId>lombok</artifactId>
		</dependency>
	</dependencies>

application.yml

server:
  port: 8081
spring:
  datasource:
    url: jdbc:mysql://localhost:3306/springcloud?serverTimezone=UTC&useUnicode=true&characterEncoding=utf-8&useSSL=true
    username: root
    password: 123123
    hikari:
      maximum-pool-size: 20
      minimum-idle: 10
  application:
    name: UserService
mybatis:
  type-aliases-package: com.leyou.userservice.pojo


eureka:
  client:
    service-url: # EurekaServer地址
      defaultZone: http://127.0.0.1:10086/eureka
  instance:
    prefer-ip-address: true # 当调用getHostname获取实例的hostname时,返回ip而不是host名称

要实现注册中心的注册还需在启动类添加注解@EnableEurekaClient

然后创建pojo、mapper、service、controller等实现数据库的查询访问。

服务消费者

服务消费者调用服务提供者实现数据访问
pom.xml配置

<dependencyManagement>
	    <dependencies>
	        <dependency>
	            <groupId>org.springframework.cloud</groupId>
	            <artifactId>spring-cloud-dependencies</artifactId>
	            <version>Greenwich.SR1</version>
	            <type>pom</type>
	            <scope>import</scope>
	        </dependency>
	    </dependencies>
	</dependencyManagement>
	

	<dependencies>
		<dependency>
		    <groupId>org.springframework.cloud</groupId>
		    <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>

		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-test</artifactId>
			<scope>test</scope>
		</dependency>
		
		<dependency>
            <groupId>com.squareup.okhttp3</groupId>
            <artifactId>okhttp</artifactId>
        </dependency>
		<dependency>
			<groupId>org.projectlombok</groupId>
			<artifactId>lombok</artifactId>
		</dependency>
	</dependencies>

application.yml配置

server:
  port: 8080
spring:
  application:
    name: consumer # 应用名称
eureka:
  client:
    service-url: # EurekaServer地址
      defaultZone: http://127.0.0.1:10086/eureka
  instance:
    prefer-ip-address: true # 当其它服务获取地址时提供ip而不是hostname
    ip-address: 127.0.0.1 # 指定自己的ip信息,不指定的话会自己寻找

启动类添加注解和http客户端

@SpringBootApplication
@EnableEurekaClient
public class UserConsumerDemoApplication {

	@Bean
	@LoadBalanced	//Robbin负载均衡
	public RestTemplate restTemplate() {
		// 这次我们使用了OkHttp客户端,只需要注入工厂即可
		return new RestTemplate(new OkHttp3ClientHttpRequestFactory());
	}

	public static void main(String[] args) {
		SpringApplication.run(UserConsumerDemoApplication.class, args);
	}
}

以上三步实现Eureka注册
服务消费者也有自己的pojo、service、controller等实现数据查询,不过是通过调用服务消费者实现,本身不直接查询数据库

以上三个应用同时启动,访问http://localhost:8080/consume?ids=16,17,18,可得到数据库数据。

高可用的Eureka Server

即Eureka Server集群,就是把EurekaServer自己也作为一个服务进行注册,这样多个EurekaServer之间就能互相发现对方,从而形成集群。
10086端口在10087进行注册,再添加一个10087在10086注册,

server:
  port: 10086 # 端口
spring:
  application:
    name: eureka-server # 应用名称,会在Eureka中显示
eureka:
  client:
    service-url: # 配置其他Eureka服务的地址,而不是自己,比如10087
      defaultZone: http://127.0.0.1:10087/eureka

启动两个Eureka Server应用就形成Eureka Server集群了。
同时客户端注册到集群时也需要做相应添加

eureka:
  client:
    service-url: # EurekaServer地址,多个地址以','隔开
      defaultZone: http://127.0.0.1:10086/eureka,http://127.0.0.1:10087/eureka

其他配置

服务提供者配置

eureka:
  instance:
    lease-expiration-duration-in-seconds: 90
    lease-renewal-interval-in-seconds: 30

lease-renewal-interval-in-seconds:服务续约(renew)的间隔,默认为30秒
lease-expiration-duration-in-seconds:服务失效时间,默认值90秒
默认情况下每个30秒服务会向注册中心发送一次心跳,证明自己还活着。如果超过90秒没有发送心跳,EurekaServer就会认为该服务宕机,会从服务列表中移除

服务消费者配置

eureka:
  client:
    registry-fetch-interval-seconds: 5

当服务消费者启动是,会检测eureka.client.fetch-registry=true参数的值,如果为true,则会从Eureka Server服务的列表只读备份,然后缓存在本地。并且每隔30秒会重新获取并更新数据。在开发环境下,能够快速得到服务的最新状态,我们可以将其设置成5。

失效剔除
有些时候,我们的服务提供方并不一定会正常下线,可能因为内存溢出、网络故障等原因导致服务无法正常工作。Eureka Server需要将这样的服务剔除出服务列表。因此它会开启一个定时任务,每隔60秒对所有失效的服务(超过90秒未响应)进行剔除。
可以通过eureka.server.eviction-interval-timer-in-ms参数对其进行修改,单位是毫秒,生成环境不要修改。
这个会对我们开发带来极大的不变,你对服务重启,隔了60秒Eureka才反应过来。开发阶段可以适当调整,比如10S

自我保护
我们关停一个服务,就会在Eureka面板看到一条警告:
在这里插入图片描述
这是触发了Eureka的自我保护机制。当一个服务未按时进行心跳续约时,Eureka会统计最近15分钟心跳失败的服务实例的比例是否超过了85%。在生产环境下,因为网络延迟等原因,心跳失败实例的比例很有可能超标,但是此时就把服务剔除列表并不妥当,因为服务可能没有宕机。Eureka就会把当前实例的注册信息保护起来,不予剔除。生产环境下这很有效,保证了大多数服务依然可用。
但是这给我们的开发带来了麻烦, 因此开发阶段我们都会关闭自我保护模式:

eureka:
  server:
    enable-self-preservation: false # 关闭自我保护模式(缺省为打开)
    eviction-interval-timer-in-ms: 1000 # 扫描失效服务的间隔时间(缺省为60*1000ms)

GIthub:Eureka
https://github.com/Jia-99/Mybatis/tree/master/Eureka

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值