注:此随笔为读书笔记。《Spring Cloud微服务实战》,想学习Spring Cloud的同伴们可以去看看此书,里面对源码有详细的解读。

什么是微服务?

  微服务是将一个原本独立的系统拆分成若干个小型服务(一般按照功能模块拆分),这些小型服务都在各自独立的进程中运行,服务之间通过基于HTTP的RESTful API进行通信协作。每个微服务维护自身的数据存储、业务开发、自动化测试案例以及独立部署机制。维护自身的数据存储称为数据管理的去中心化。由于数据管理的去中心化,各个微服务的数据一致性成为一个难题,因此,需要强调的是各个服务之间进行无“事务”的调用。

  微服务架构中针对不同应用场景和出现的各种问题出现了各种解决方案和开源框架。服务治理:阿里的Dubbo、当当网扩展的Dubbox、Netflix的Eureka、Apache的Consul等;分布式配置管理:百度的Disconf、Spring cloud的Config、淘宝的Diamond等;批量任务:当当网的Elastic-Job、Spring Cloud的Task等;服务跟踪:京东的Hydra、Spring Cloud的Sleuth等;等等。

  Spring Cloud不只是解决微服务中的某一个问题,而是一个解决微服务架构实施的综合性解决框架,它整合了诸多被广泛实践和证明过的框架作为实施的基础部件,又在该体系基础上创建了一些优秀的边缘组件。如Spring Cloud Eureka、Spring Cloud Ribbon、Spring Cloud Hytrix、Spring Cloud Feign等针对微服务的解决方案。

  Spring Cloud是一个基于Spring Boot实现的微服务框架,针对微服务应用的不同场景,产生了各种技术架构:

    1.Spring Cloud Config:配置管理工具;

    2.Spring Cloud Netflix:Spring Cloud的核心组件,对多个Netflix OSS开源套件进行整合;

      a.Eureka:服务治理组件,包含服务注册中心、服务注册、服务发现和消费机制的实现;

      b.Hystrix:容错管理组件,实现断路由器模式,帮助服务依赖中出现的延迟和故障提供强大的容错能力;

      c.Ribbon:客户端负载均衡的服务调用组件;

      d.Feign:基于Ribbon和Hystrix的声明式服务调用组件,是对两者的整合;

      e.Zuul:网关组件,提供智能路由、访问过滤等功能。

      f.Archaius:外部化配置组件。

    3.Spring Cloud Bus:事件、消息总线,用于传播集群中的状态变化或事件,以触发后续的处理,比如用来动态刷新配置等;

    4.Spring Cloud Cluster:针对Zookeeper、Redis、Hazelcast、Consul的选举算法和通用状态模式的实现;

    5.Spring Cloud Stream:通过Redis、Rabbit和Kafka实现的消费服务,可以通过简单的声明式模型来发送和接收消息;

    6.Spring Cloud Sleuth:Spring Cloud应用的分布式跟踪实现,可以完美整合Zipkin;

    7.Spring Cloud Zookeeper:基于Zookeeper的服务发现与配置管理组件。等等。

  Spring Cloud Eureka主要负责微服务架构当中的微服务治里工作,是微服务架构当中最为核心和基础的模块,用来实现各个微服务的服务注册和服务发现。

  Spring Cloud Eureka,使用Netflix Eureka来实现微服务的注册和发现,包括服务端组件和客户端组件,服务端和客户端组件均有java语言编写的,所以Eureka主要使用于java语言的分布式系统。但是,它也支持非java语言的微服务架构,只是,需要程序员自己来实现Eureka的客户端程序。一些开放平台上有一些客户端框架,例如,.NET平台的Steeltoe、Node.js的eureka-js-client等。这里说的服务端就是注册中心,客户端就是一些微服务。

  Eureka服务治理体系有三大核心角色:服务注册中心、服务提供者以及服务消费者。服务注册中心一般称为Eureka服务端,服务提供者和服务消费者称为Eureka客户端。

本随笔涉及的开发工具:IDEA,技术框架:Spring Boot和Spring Cloud

1.搭建服务注册中心(单节点模式)

1.创建一个基础的Spring Boot项目,命名:eureka-server,pom.xml内容

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion> <groupId>com.example</groupId>
<artifactId>demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging> <name>demo-eureka</name>
<description>Demo project for Spring Boot</description> <parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.3.7.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent> <properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
</properties> <dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka-server</artifactId>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Camden.SR4</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>
</project>

pom.xml

2.Spring Boot启动类中添加注解@EnableEurekaServer

package com.example.eurekaserver;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer; @EnableEurekaServer
@SpringBootApplication
public class Application { public static void main(String[] args) {
new SpringApplicationBuilder(Application.class).web(true).run(args);
}
}

Application.java

3.Spring Boot配置文件信息,里面有两点需要注意

server:
port: 1111
eureka:
instance:
hostname: localhost
client:
register-with-eureka: false #1. false:代表不让注册中心注册自己
fetch-registry: false #2. false:注册中心职责是维护服务实例,不需要去检索服务
serviceUrl:
default: http://${eureka.instance.hostname}:${server.port}/eureka/

采用yml文件,只需将application.properties文件后缀改成application.yml即可。

4.项目结构:

5.浏览器输入http://localhost:1111/,即可看到Eureka信息面板。

2.注册微服务(服务提供者)

  提供服务的应用可以是Spring Boot应用,也可以是其他技术平台且遵循Eureka通信机制的应用。将自己的应用注册到注册中心Eureka,以供其他应用使用。

1.创建一个Spring Boot项目,命名:demo-server,pom.xml文件内容

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging> <name>demo-server</name>
<description>Demo project for Spring Boot</description> <parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.7.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent> <properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.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-eureka</artifactId>
</dependency>
</dependencies> <dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Camden.SR4</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>
</project>

pom.xml

2.测试Controller

@RestController
public class HelloController { @Autowired
private DiscoveryClient discoveryClient; @RequestMapping(value = "/hello", method = RequestMethod.GET)
public String index() {
ServiceInstance instance = discoveryClient.getLocalServiceInstance();
return "hello world! host:" + instance.getHost() + ", service_id" + instance.getServiceId();
}
}

HelloController.java

3.启动类添加注解@EnableDiscoverClient

@EnableDiscoveryClient
@SpringBootApplication
public class DemoServerApplication { public static void main(String[] args) {
SpringApplication.run(DemoServerApplication.class, args);
}
}

4.配置文件信息 application.yml

spring:
application:
name: demo-service
eureka:
client:
serviceUrl:
defaultZone: http://localhost:1111/eureka/ #指定注册中心

5.启动项目,可以看到微服务已经注册到注册中心

3.服务发现和消费

  服务消费者,会做两件事,服务发现和服务消费,服务发现由Eureka的客户端完成,服务消费由Ribbon完成。Ribbon是一个基于Http和Tcp的负载均衡器,它可以根据客户端(一般指服务消费者)中配置的ribbonServerList服务列表以轮询的方式访问,以达到负载均衡的作用。

1.创建一个ribbon-consumer项目,pom.xml中添加 spring-cloud-starter-ribbon包

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion> <groupId>com.example</groupId>
<artifactId>demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging> <name>ribbon-consumer</name>
<description>Demo project for Spring Boot</description> <parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.3.7.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent> <properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.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-eureka</artifactId>
</dependency> <dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-ribbon</artifactId>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Camden.SR4</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> </project>

pom.xml

2.启动类

package com.example.demo;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.web.client.RestTemplate; @EnableDiscoveryClient
@SpringBootApplication
public class RibbonConsumerApplication { @Bean
@LoadBalanced
RestTemplate restTemplate() {
return new RestTemplate();
} public static void main(String[] args) {
SpringApplication.run(RibbonConsumerApplication.class, args);
}
}

RibbonConsumerApplication.java

3.controller

@RestController
public class ConsumerController { @Autowired
private RestTemplate restTemplate; @RequestMapping(value = "/ribbon-consumer", method = RequestMethod.GET)
public String helloConsumer() {
return restTemplate.getForEntity("http://DEMO-SERVICE/hello", String.class).getBody();
}
}

ConsumerController.java

4.配置文件

server:
port: 9001
spring:
application:
name: ribbon-consumer
eureka:
client:
serviceUrl:
defaultZone: http://localhost:1111/eureka/

application.yml

4.测试

用不同端口启动两个demo-server服务,用来测试ribbon的负载均衡(在demo-server中的接口添加打印日志,可以在控制台看出那个服务被调用)

java -jar demo-0.0.1-SNAPSHOT.jar --server.port=8081
java -jar demo-0.0.1-SNAPSHOT.jar --server.port=8082

启动ribbon-consumer项目

注册中心

访问http://localhost:9001/ribbon-consumer

4.高可用注册(高可用模式)

  两个注册服务互相注册即可实现高可用。

1.在第一个搭建的服务注册中心项目eureka-server上,将原来的application.yml注释,新建两个application-peer1.yml和application-peer2.yml

server:
port: 1111 spring:
profiles: peer1
eureka:
instance:
hostname: peer1
client:
serviceUrl:
defaultZone: http://peer2:1112/eureka/

application-peer1

server:
port: 1112 spring:
profiles: peer2
eureka:
instance:
hostname: peer2
client:
serviceUrl:
defaultZone: http://peer1:1111/eureka/

application-peer2

2.启动项目即可

3.修改demo-server项目中的配置文件,添加信息如下

spring:
application:
name: demo-service
eureka:
client:
serviceUrl:
defaultZone: http://peer1:1111/eureka/,http://peer2:1112/eureka/

然后启动该项目,即该服务皆注册到两个注册中心。

此时,若其中一个注册中心挂掉,那么另外一个注册中心可以继续使用。

1 Spring Cloud Eureka服务治理(上)的更多相关文章

  1. 1 Spring Cloud Eureka服务治理

    注:此随笔为读书笔记.<Spring Cloud微服务实战> 什么是微服务? 微服务是将一个原本独立的系统拆分成若干个小型服务(一般按照功能模块拆分),这些小型服务都在各自独立的进程中运行 ...

  2. 笔记:Spring Cloud Eureka 服务治理

    Spring Cloud Eureka 是 Spring Cloud Netflix 微服务套件的一部分,基于 Netflix Eureka 做了二次封装,主要负责完成微服务架构中的服务治理功能,服务 ...

  3. Spring Cloud Eureka 服务治理

    Spring Cloud Eureka 是 Spring Cloud Netflix 微服务套件的一部分,基于 Netflix Eureka 做了二次封装,主要负责完成微服务架构中的服务治理功能,服务 ...

  4. Spring cloud Eureka 服务治理(注册服务提供者)

    搭建完成服务注册中心,下一步可以创建服务提供者并向注册中心注册服务. 接下来我们创建Spring Boot 应用将其加入Eureka服务治理体系中去. 直接使用签名章节创建hello服务项目改造: 1 ...

  5. Spring cloud Eureka 服务治理(搭建服务注册中心)

    服务之类是微服务架构中最为核心的基础模块,它主要用来实现各个微服务实例的自动化注册和发现. 1. 服务注册 在服务治理框架中,通常会构建一个注册中心,每个服务单元向注册中心登记自己提供的服务,将主机. ...

  6. 1 Spring Cloud Eureka服务治理(下)

    注:此随笔为读书笔记.<Spring Cloud微服务实战> 上篇主要介绍了什么是微服务以及微服务治理的简单实现,如微服务注册中心的实现.微服务注册的实现.微服务的发现和消费的实现.微服务 ...

  7. Spring cloud Eureka 服务治理(高可用服务中心)

    在微服务的架构中,我们考虑发生故障的情况,所以在生产环境中我们需要对服务中各个组件进行高可用部署. Eureka Server 的高可用实际上就是将自己作为服务想其它服务注册中心注册自己,这样就形成了 ...

  8. Spring Cloud Eureka 服务治理机制

     服务提供者         服务提供者在启动的时候会通过发送REST请求的方式将自己注册到Eureka Server上,同时带上了自身服务的一些元数据信息.Eureka Server 接收到这个RE ...

  9. spring cloud Eureka 服务注册发现与调用

    记录一下用spring cloud Eureka搭建服务注册与发现框架的过程. 为了创建spring项目方便,使用了STS. 一.Eureka注册中心 1.新建项目-Spring Starter Pr ...

随机推荐

  1. 10款最好的Python IDE

    Python 的学习过程少不了集成开发环境(IDE)或者代码编辑器.这些 Python 开发工具帮助开发者加快使用 Python 开发的速度,提高效率.高效的代码编辑器或者 IDE 应该会提供插件,工 ...

  2. Self-Taught Learning to Deep Networks

    In this section, we describe how you can fine-tune and further improve the learned features using la ...

  3. 二分图简单概念&&HDU 2063

    二分图: 二分图又称作二部图,是图论中的一种特殊模型. 设G=(V,E)是一个无向图,如果顶点V可分割为两个互不相交的子集(A,B),并且图中的每条边(i,j)所关联的两个顶点i和j分别属于这两个不同 ...

  4. vue prpos

    匹配某些值中的一个 type: { validator: function(value) { return ["success", "warning", &qu ...

  5. javascript创建对象的方法--基本模式

    javascript创建对象的方法--基本模式 一.总结 关注本质 二.代码 <!DOCTYPE html> <html lang="zh-cn"> < ...

  6. php全局变量的使用

    php全局变量的使用 一.总结 1.php的全局变量:php的全局变量和C++,Java的全局变量不一样 2.页面嵌套php:我在html页面中嵌套php代码的时候,php的全局变量好像和C++,Ja ...

  7. 使用Notepad++的XML Tools插件格式化XML文件

    转自“”:https://blog.csdn.net/qq_36279445/article/details/79803310 1. 安装XML Tools插件 (1) 通过网址http://sour ...

  8. Android 安卓直播开源: RTMP 推流SDK

    前些日子在github上提交了基于GPUImage的iOS直播推流SDK(https://github.com/runner365/GPUImageRtmpPush) 最近整理了Android直播推流 ...

  9. BZOJ3510首都(LCT)

    Description 在X星球上有N个国家,每个国家占据着X星球的一座城市.由于国家之间是敌对关系,所以不同国家的两个城市是不会有公路相连的. X星球上战乱频发,如果A国打败了B国,那么B国将永远从 ...

  10. Docker+Mongodb

    原文:Docker+Mongodb docker search mongodb docker run -d -p 2701:27017 -v /usr/mongodb/data:/data/db  - ...