注:此随笔为读书笔记。《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. 笔记:Spring Cloud Eureka 服务治理

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

  2. Spring Cloud Eureka 服务治理

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

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

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

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

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

  5. 1 Spring Cloud Eureka服务治理(上)

    注:此随笔为读书笔记.<Spring Cloud微服务实战>,想学习Spring Cloud的同伴们可以去看看此书,里面对源码有详细的解读. 什么是微服务? 微服务是将一个原本独立的系统拆 ...

  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. 在 ASP.NET Core 中执行租户服务

    在 ASP.NET Core 中执行租户服务 不定时更新翻译系列,此系列更新毫无时间规律,文笔菜翻译菜求各位看官老爷们轻喷,如觉得我翻译有问题请挪步原博客地址 本博文翻译自: http://gunna ...

  2. Javaweb向服务器上传文件以及从服务器下载文件的方法

    先导入jar包 点击下载 commons-fileupload是Apache开发的一款专门用来处理上传的工具,它的作用就是可以从request对象中解析出,用户发送的请求参数和上传文件的流. comm ...

  3. Composer简介及使用实例

    1.PHP-FIG 官网:http://www.php-fig.org/ php编码规范: 本文档是PHP互操作性框架制定小组(PHP-FIG :PHP Framework Interoperabil ...

  4. 【渗透笔记】友情检测朋友公司并拿下shell过程

    一朋友在一个百货公司上班,由于无聊危险漫步就友情检测了他们公司的网站,开始我们的检测之旅吧. 打开网站,发现网站挺不错,不愧是大卖场,页面做的挺花,但是安全性怎么样呢?来试试吧.先用工具扫了下后台,结 ...

  5. sublime中css输入分号后自动提示的烦恼

    sublime开发前端确实好用,有好多些个的插件,轻量便捷,但是在使用sublime中的一些插件的时候总是会遇到困扰,跟自己想象中的不一样,比如在使用SublimeCodeIntel插件的时候,就会遇 ...

  6. 在Intellij IDEA中使用Debug

    Debug用来追踪代码的运行流程,通常在程序运行过程中出现异常,启用Debug模式可以分析定位异常发生的位置,以及在运行过程中参数的变化.通常我们也可以启用Debug模式来跟踪代码的运行流程去学习三方 ...

  7. Linux虚拟机之间实现密钥登陆

    Server1与Server2在同一虚拟网络当中,在Server2中使用Server1的Hostname连接Server1,并且无需密码认证. Server1,  Hostname:  hlmvmea ...

  8. C++ operator bool

    雕虫小技: #include <iostream> struct A{ operator bool(){ return false; } }; int main() { A a{}; if ...

  9. PHP初入,简易网页整理(布局&特效的使用)

    html><html> <head> <meta charset="UTF-8"> <title></title> ...

  10. 关于js中单双引号以及转义符的理解

    关于js中单引号(')和双引号(")的使用以及转义的理解 这几天一直在画页面,身为开发人员的我之所以要画页面是因为当前项目中的页面上所有的东西都是从数据库中取得的,也就是动态的,类似于我们设 ...