中文api
https://www.springcloud.cc
一、springcloud 是一套完整的微服务解决方案框架
流程:
- 请求统一通过 API 网关(Zuul)来访问内部服务。
- 网关接收到请求后,从注册中心(Eureka)获取可用服务。
- 由 Ribbon 进行均衡负载后,分发到后端具体实例。
- 微服务之间通过 Feign 进行通信处理业务。
- Hystrix 负责处理服务超时熔断。
- Turbine 监控服务间的调用和熔断相关指标。
- Spring Cloud Config 配置中心,利用 Git 集中管理程序的配置。
- Spring Cloud Netflix 集成众多Netflix的开源软件。
- Spring Cloud Netflix Eureka 服务中心(类似于管家的概念,需要什么直接从这里取,就可以了),一个基于 REST 的服务,用于定位服务,以实现云端中间层服务发现和故障转移。
- Spring Cloud Netflix Hystrix 熔断器,容错管理工具,旨在通过熔断机制控制服务和第三方库的节点,从而对延迟和故障提供更强大的容错能力。
- Spring Cloud Netflix Zuul 网关,是在云平台上提供动态路由,监控,弹性,安全等边缘服务的框架。Web 网站后端所有请求的前门。
- Spring Cloud Netflix Archaius 配置管理 API,包含一系列配置管理API,提供动态类型化属性、线程安全配置操作、轮询框架、回调机制等功能。
- Spring Cloud Netflix Ribbon 负载均衡。
- Spring Cloud Netflix Fegin REST客户端。
- Spring Cloud Bus 消息总线,利用分布式消息将服务和服务实例连接在一起,用于在一个集群中传播状态的变化。
- Spring Cloud for Cloud Foundry 利用 Pivotal Cloudfoundry 集成你的应用程序。
- Spring Cloud Cloud Foundry Service Broker 为建立管理云托管服务的服务代理提供了一个起点。
- Spring Cloud Cluster 集群工具,基于 Zookeeper, Redis, Hazelcast, Consul 实现的领导选举和平民状态模式的抽象和实现。
- Spring Cloud Consul 基于 Hashicorp Consul 实现的服务发现和配置管理。
- Spring Cloud Security 安全控制,在 Zuul 代理中为 OAuth2 REST 客户端和认证头转发提供负载均衡。
- Spring Cloud Sleuth 分布式链路监控,SpringCloud 应用的分布式追踪系统,和 Zipkin,HTrace,ELK 兼容。
- Spring Cloud Data Flow 一个云本地程序和操作模型,组成数据微服务在一个结构化的平台上。
- Spring Cloud Stream 消息组件,基于 Redis,Rabbit,Kafka 实现的消息微服务,简单声明模型用以在 Spring Cloud 应用中收发消息。
- Spring Cloud Stream App Starters 基于 Spring Boot 为外部系统提供 Spring 的集成。
- Spring Cloud Task 短生命周期的微服务,为 Spring Booot 应用简单声明添加功能和非功能特性。
- Spring Cloud Task App Starters。
- Spring Cloud Zookeeper 服务发现和配置管理基于 Apache Zookeeper。
- Spring Cloud for Amazon Web Services 快速和亚马逊网络服务集成。
- Spring Cloud Connectors 便于PaaS应用在各种平台上连接到后端像数据库和消息经纪服务。
- Spring Cloud Starters (项目已经终止并且在 Angel.SR2 后的版本和其他项目合并)
- Spring Cloud CLI 命令行工具,插件用 Groovy 快速的创建 Spring Cloud 组件应用。
二、服务治理
三、eureka
server
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.8.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<properties>
<java.version>1.8</java.version>
<spring-cloud.version>Greenwich.SR3</spring-cloud.version>
<maven-jar-plugin.version>3.1.1</maven-jar-plugin.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</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>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
配置文件
server.port=8100 eureka.instance.hostname=localhost ##因为自己是注册中心,是否需要将自己注册给自己的注册中心,集群环境要设成true eureka.client.registerWithEureka=false ##因为自己是注册中心,不需要去检索服务信息 eureka.client.fetchRegistry=false eureka.client.serviceUrl.defaultZone=http://${eureka.instance.hostname}:${server.port}/eureka/ ##关闭自我保护 2秒钟收不到客户端服务的心跳及时剔除服务 #eureka.server.enable-self-preservation = false #eureka.server.eviction-interval-timer-in-ms:2000
@SpringBootApplication @EnableEurekaServer /** * server 注册中心集群,server 建多个 * * spring.application.name 要相同 * * * client: registerWithEureka: true fetchRegistry: true serviceUrl: ###server.port端口号为另一个注册中心的端口号 defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/ 如果是三台机器做集群另两台的注册中心地址 http://${eureka.instance.hostname}:${server.port}/eureka/,http://${eureka.instance.hostname}:${server.port}/eureka/ * * 注册中心不是每个注册中心服务中都有会员服务和订单服务的,只保证一个注册中心服务中有订单服务和会员服务, * 当一台注册中心服务挂掉的时候会将订单服务和会员服务通过到另一个注册中心中默认30秒 * * * * * Eureka 自我保护机制 * 分为两种角色 * EurekaClient 注册中心客户端 * EurekaServer 注册中心服务端 * * 为什么需要自我保护 * * 两台会员服务,当有一个会员服务DOWN后,会报错,注册中心里还有, * 为了防止EurekaClient 可以正常运行,但是与EurekaServer 网络不通的情况下 * EurekaServer 不会将EurekaClient 服务进行剔除 * * 自我保护机制:默认情况下EurekaClient定时向EurekaServer端发送心跳包 * 在一定时间内如果没有收到,便会直接从服务中心剔除该服务,默认90S * 但是在短时间内丢失了大量的服务实例心跳,这时候会开启自我保护机制,不会去剔除该服务 * 为了防止EurekaClient是可以正常访问,但是只是EurekaClient与EurekaServer网络不通 * 在什么环境开启自我保护机制 * * 本地环境 * 建议在本地环境禁止 * * 生产环境 * 建议开启自我保护机制 * * 关闭自我保护机制 在中心端 * * eureka: * server: * enable-self-preservation:false * eviction-interval-timer-in-ms:2000 2s中剔除 * * 在客户端 * eureka: * instance: * ##客户端向服务端发送心跳的时间间隔,单位为秒(客户端告诉服务端自己会按照该规则) * lease-renewal-interval-in-seconds:1 * ##服务端在收到最后一次心跳之后等待的时间上限,单位为秒,超过则删除(客户端告诉服务端自己会按照该规则) * lease-expiration-duration-in-seconds:2 * * * 注册中心中的服务默认缓存30秒 * * 如果服务真的宕机了,手动在注册中心把该服务踢掉,本地掉用应该重试机制,做好服务降级 * * zookerper 没有服务保护机制 临时节点,节点唯一 * * ribbon 是springcloud 本地(客户端)负载均衡 * * * */ public class App { public static void main(String[] args) { SpringApplication.run(App.class, args); } }
客户端
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.8.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<properties>
<java.version>1.8</java.version>
<spring-cloud.version>Greenwich.SR3</spring-cloud.version>
<maven-jar-plugin.version>3.1.1</maven-jar-plugin.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<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-test</artifactId>
<scope>test</scope>
</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>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
配置文件
spring.application.name=app-member server.port=8200 eureka.client.registerWithEureka=true eureka.client.fetchRegistry=true ##注册中心的地址(将该服务注册到地址为http://localhost:8100/eureka的注册中心中) eureka.client.serviceUrl.defaultZone=http://localhost:8100/eureka
@RestController public class MemberApi { /** * * springcloud中接口制件调用有两种方式 * 1.RestTemplate * 2.fegin * * * **/ @Autowired private RestTemplate restTemplate; @RequestMapping(value="/addMember") public String addMember(String name) { //url = "http://localhost:8300/getUser" /** * restTemplate.getForObject("http://localhost:8300/getUser", String.class); * restTemplate 以别名的方式访问需要添加 * * * **/ String s = restTemplate.getForObject("http://app-user/getUser", String.class); System.out.println(s); return "添加会员"; } }
eureka 和zookeeper 对别 cpa理论???
四、zookeeper注册中心
把 zk-member,zk-user服务注册到zookeeper中,在zk-member服务中调用zk-user服务
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.8.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<properties>
<java.version>1.8</java.version>
<spring-cloud.version>Greenwich.SR3</spring-cloud.version>
<maven-jar-plugin.version>3.1.1</maven-jar-plugin.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-zookeeper-all</artifactId>
<exclusions>
<exclusion>
<groupId>org.apache.zookeeper</groupId>
<artifactId>zookeeper</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.apache.zookeeper</groupId>
<artifactId>zookeeper</artifactId>
<version>3.4.6</version>
<exclusions>
<exclusion>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</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>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
配置文件
spring.application.name=zk-user
server.port=9100
#只能是本地才能这么写,如果连接远程需要加bootstrap.yml,zookeeper创建的是临时节点,服务关掉后节点也会被删除
#spring.cloud.zookeeper.connect-string=localhost:2181
bootstrap.yml
spring: cloud: zookeeper: discovery: instancePort: ${server.port} #端口号 #instanceHost: yellowcong.com #当前服务的初始化地址(可以不填) enabled: true register: true connectString: 192.168.233.100:2181 # 多节点配置,通过逗号分割192.168.253.31:2181,192.168.253.32:2181
zk-user
@SpringBootApplication /** * 使用zookeeper 或使用connsoul时@EnableDiscoveryClient注册到注册中心 * @author Administrator * */ @EnableDiscoveryClient public class App { public static void main(String[] args) { SpringApplication.run(App.class, args); } }
zk-member
@SpringBootApplication @EnableDiscoveryClient public class App { public static void main(String[] args) { SpringApplication.run(App.class, args); } /** * 将RestTemplate注入spring容器 * @return */ @Bean @LoadBalanced //加入ribbon 的负载均衡器 ,轮询调用 RestTemplate restTemplate() { return new RestTemplate(); } }
@RestController public class MemberApi { /** * * springcloud中接口制件调用有两种方式 * 1.RestTemplate * 2.fegin * * * **/ @Autowired private RestTemplate restTemplate; @Autowired private DiscoveryClient discoveryClient; @RequestMapping(value="/addMember") public String addMember(String name) { //url = "http://localhost:8300/getUser" //通过discoveryClient 获取服务信息列表 List<ServiceInstance> services = discoveryClient.getInstances("zk-user"); /** * restTemplate.getForObject("http://localhost:8300/getUser", String.class); * restTemplate 以别名的方式访问需要添加 * * * **/ String s = restTemplate.getForObject("http://zk-user/getUser", String.class); System.out.println(s); return "添加会员"; } }
五、consoul注册中心