1.微服务的特点
1.按业务划分为一个独立运行的程序
2.服务之间通过HTTP协议相互通信,这个通信机制和平台语言无关,通信的数据格式JSON,XML,还有比json更轻量的Protobuf , 是一种平台无关、语言无关、可扩展且轻便高效的序列化数据结构的协议,可以用于网络通信和数据存储。将数据序列化成 二进制数据,高效但是可读性差。HTTP协议通信机制的缺点是机制不可靠,虽然成功率高,但是也有失败的时候。
3.自动化部署,随着服务数的增加,按照单体的部署方式来每个服务都去按照单体结构的项目来部署会很复杂。
4.可以使用不同的编程语言和储存技术
5.服务集中化管理 springcloud中服务的治理采用的是Eureka
6.微服务是一个分布式系统
7.在高并发的情况下为了防止服务雪崩的效应,采取了熔断机制,直接返回请求失败信息,解决大量线程阻塞的问题。熔断器有自我修复功能。
8.微服务在CAP理论中采用的是AP架构,即高可用和分区容错,C呢是一致性,这个主要是由分布式事务来解决。
9.微服务是核心,Docker为容器技术,DevOps是一种部署的手段或者理念。
2.微服务的功能
1.服务的注册和发现,一个服务注册以后会定时向服务的注册中心提供心跳,以表明自己还处于可用的状态,如果停止提供心跳会被注册中心剔除服务注册列表,再提供心跳会被加入注册列表。
2.服务的负载均衡。所有的注册了的服务都可以从注册中心拿到所有服务的注册列表信息,服务的消费者会集成负载均衡组件,该组件会向服务消费者获取服务注册列表信息,并每隔一段时间刷新,当消费者消费服务时,负载均衡组件通过负载均衡策略选择选择一个服务提供者进行消费。
3.服务的容错,当某一个服务不可用的时候,高并发下用户的请求都会处于阻塞的状态,短时间内导致服务器的线程资源耗尽,所以有熔断器,请求失败次数超过一定的阀值,断路器打开,快速返回失败,一段时间后处于半打开状态,如果正常请求则关闭断路器,自我修复成功。
4.服务网关。在为服务系统中,API接口资源通常是由服务网关统一暴露,这样可以将内部服务隐藏起来,API网关有请求转发的作用,另外可能需要负责一定的安全验证,比如用户身份验证,权限判断,最终转发到具体的服务。还可以实现监控功能,实时日志输出,流量监控服务降级等等。通常使用zuul,nginx作为网关。
5.服务配置的统一管理,SpringCloud使用的就是Config,有一个服务就是配置服务,他需要读取配置文件仓库的信息来启动配置服务,配置服务启动以后需要读取配置文件的信息,读来放在配置服务的内存之中。启动其他额服务的时候他们就会向配置服务读取配置信息。当配置修改过后,会向配置服务发送post请求进行刷新,同时其他的服务也会向配置服务重新读取配置文件。
6.服务链路追踪。主要是厘清各个服务的调用链关系,常用的有谷歌的Dapper,阿里的鹰眼。
7.实时日志。
3.Eureka
Eureka有两个角色 Eureka Server 和Eureka Client .第一个提到共服务注册和发现功能,第二个是服务提供和服务消费。服务的消费过程如下:
服务提供者向注册中心注册,将自己的信息比如ip地址和服务名,通过Rest APi的形式提交给服务注册中心,Eureka Server。同样服务消费者也会向注册中心注册,同时服务消费者会获得服务注册列表的信息,这样服务消费者就知道了服务提供者的ip地址。可以通过http远程调度来消费服务提供者的服务。
因为要用到多个SpringBoot工程,所以创建一个Maven主工程。
配置pom文件:父依赖中需要添加工程的共同依赖,springBoot的依赖和编码,版本为Finchley.RELEASE的springCloud依赖。还有springboot的maven插件,这样就可以用maven插件的方式来启动工程。
<?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.wx</groupId>
<artifactId>learnspringcloud</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>pom</packaging>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.3.RELEASE</version>
<relativePath/>
</parent>
<modules>
<module>eurekaserver</module>
</modules>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
<spring-cloud.version>Finchley.RELEASE</spring-cloud.version>
</properties>
<dependencies>
<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>
</project>
创建一个Model,命名为Eureka-Server,采用Spring Initializr的方式创建:
pom文件引入父工程依赖,eurekaserver的起步依赖和springboot测试的起步依赖,还有maven插件依赖,
<?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>
<parent>
<groupId>com.wx</groupId>
<artifactId>learnspringcloud</artifactId>
<version>1.0-SNAPSHOT</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.wx</groupId>
<artifactId>eureka-server</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>eureka-server</name>
<description>Demo project for Spring Boot</description>
<dependencies>
<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>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
yml配置:
server:
port: 8761
eureka:
instance:
hostname: localhost
client:
registerWithEureka: false
fetchRegistry: false
serviceUrl:
defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/
spring:
application:
name: eurka-server
registerWithEureka: false fetchRegistry: false 来防止自己向自己注册,表明自己是一个server
加入注解 @EnableEurekaServer,开启euraka Server功能。
编写一个Eureka Client 同样会创建Model
pom文件:添加父依赖,springboot的web依赖,测试起步依赖,和eureka client的起步依赖。
<?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>
<parent>
<groupId>com.wx</groupId>
<artifactId>learnspringcloud</artifactId>
<version>1.0-SNAPSHOT</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.wx</groupId>
<artifactId>eureka-client</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>eureka-client</name>
<description>Demo project for Spring Boot</description>
<dependencies>
<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>
<!-- https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-starter-eureka -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka</artifactId>
<version>1.4.4.RELEASE</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
yml文件:
server:
port: 8762
spring:
application:
name: service-hi
eureka:
client:
serviceUrl:
defaultZone: http://localhost:8761/eureka/
编写测试:
@RestController
public class TestController {
@Value("${server.port}")
String port;
@GetMapping("/hi")
public String home(@RequestParam String name){
return "hi,"+name+",port:"+port;
}
}
测试: