现在微服务架构越来越普及,目前接触到主要有dubbo和springcloud
在springcloud中使用euerkaserver作为服务的注册和发现的中心
简单搭建EuerkaServer
1 在eclipse新建一个maven项目,在pom.xml文件中添加相关依赖
<!-- 添加eureka-server -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka-server</artifactId>
</dependency>
<!-- 添加springboot -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<parent>
<!-- Your own application should inherit from spring-boot-starter-parent -->
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.4.RELEASE</version>
</parent>
完整的pom.xml
<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>
<!-- Your own application should inherit from spring-boot-starter-parent -->
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.4.RELEASE</version>
</parent>
<artifactId>EuerkaServer</artifactId>
<groupId>com.wxf.SpringCloud</groupId>
<name>Spring Boot Actuator Sample</name>
<description>Spring Boot Actuator Sample</description>
<version>0.0.1-SNAPSHOT</version>
<url>http://projects.spring.io/spring-boot/</url>
<organization>
<name>Pivotal Software, Inc.</name>
<url>http://www.spring.io</url>
</organization>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka-server</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</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-security</artifactId>
</dependency>
-->
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Dalston.SR1</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>
2 添加启动类
在启动类加入注解@EnableEurekaServer
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@EnableEurekaServer
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
3 修改application.properties内容
spring.application.name=com.wxf.SpringCloud.EuerkaServer.actuator.Application
server.port=1111
#强制不注册到注册服务器
eureka.client.register-with-eureka=false
eureka.client.fetch-registry=false
#注册中心地址
eureka.client.serviceUrl.defaultZone=http://localhost:${server.port}/eureka/
#驱逐下线的服务,间隔,5秒,默认是60,建议开发和测试环境配置
#org.springframework.cloud.netflix.eureka.server.EurekaServerConfigBean.evictionIntervalTimerInMs
eureka.server.evictionIntervalTimerInMs=5000
4 登陆管理页面

搭建生产者
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>
<artifactId>SpringCloud.Client</artifactId>
<groupId>com.wxf.SpringCloud</groupId>
<name>Spring Boot Actuator Sample</name>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.4.RELEASE</version>
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka</artifactId>
</dependency>
<!--端口监控依赖包-->
<!-- <dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Dalston.SR1</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>
启动类
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
@EnableEurekaClient
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
application.properties
spring.application.name=Application-Provider
server.port=8181
#注册中心地址
eureka.client.serviceUrl.defaultZone=http://localhost:1111/eureka/
management.endpoints.enabled-by-default=false
接下来我们进入euerka管理页面
搭建消费者
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>
<artifactId>SpringCloud.Client</artifactId>
<groupId>com.wxf.SpringCloud</groupId>
<name>Spring Boot Actuator Sample</name>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.4.RELEASE</version>
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka</artifactId>
</dependency>
<!-- <dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--服务调用-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-feign</artifactId>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Dalston.SR1</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>
启动类
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.cloud.netflix.feign.EnableFeignClients;
@EnableDiscoveryClient
@EnableFeignClients
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
控制层
controller
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
@RestController
public class controller {
@Autowired
Service serviceAFeignClient;
@RequestMapping(value = "/*",method = RequestMethod.GET)
@ResponseBody
public String getHello(){
String hi = serviceAFeignClient.hi();
if (hi.isEmpty()){
hi="远程调用失败";
}
else {
hi="收到远程信息"+hi;
}
return hi;
}
}
service
import org.springframework.cloud.netflix.feign.FeignClient;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.RequestMapping;
@Component
@FeignClient(value = "Application-Provider") //这里的name对应调用服务的spring.applicatoin.name
public interface Service {
@RequestMapping(value = "/hi")
String hi();
}
运行后在euerka注册中心中可以到到服务
访问消费者,成功调用了提供者暴露的接口
上述内容已经完成了简单的服务注册、发现与调用。
注意事项:
注解:
-
@EnableEurekaServer
启动服务注册中心
-
@EnableDiscoveryClient
注册服务至注册中心(不单是euerka)
-
@EnableEurekaClient
注册服务至注册中心(只能是euerka)
-
@EnableFeignClients
需要在启动项上加上才可以调用FeignClient
-
@FeignClient(value = “Application-Provider”)
调用外部服务接口
依赖包:
<!-- euerka注册中心-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka</artifactId>
</dependency>
<!-- 外部服务调用-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-feign</artifactId>
</dependency>
疑问
服务是如何注册和发现的?
点击这里
Euerka Server
- 注册:各个微服务启动时,会通过Eureka Client向Eureka Server进行注册自己的信息(例如服务信息和网络信息),Eureka Server会存储该服务的信息。
- 调用:服务消费者在调用服务时,本地Eureka Client没有的情况下,会到Eureka Server拉取信息。
-
维护:
Cancel 服务下线–Eureka客户端在程序关闭时向Eureka服务器发送取消请求
Eviction 服务剔除–当Eureka客户端连续90秒没有向Eureka服务器发送服务续约,即心跳,Eureka服务器会将该服务实例从服务注册列表删除,即服务剔除。
renew 服务续约–Eureka Client会每隔30秒发送一次心跳来续约。 通过续约来告知Eureka Server该Eureka客户仍然存在,没有出现问题。
服务信息如何同步?
为保证服务的高可用,一般会部署多个EuerkaServer,防止其中某个注册中心出现宕机影响服务的调用。
每个Eureka Server同时也是Eureka Client,多个Eureka Server之间通过P2P复制的方式完成服务注册表的同步。同步时,被同步信息不会同步出去。也就是说有3个Eureka Server,Server1有新的服务信息时,同步到Server2后,Server2和Server3同步时,Server2不会把从Server1那里同步到的信息同步给Server3,只能由Server1自己同步给Server3。
负载均衡?
点这里
点这里
在springcloud中,使用的是ribbon来解决负载均很的问题,而常见的负载均衡策略包括有:
IRule 是 ribbon负载均衡的父接口
RandomRule | 随机 | 随机选择一个服务实例 |
RoundRobinRule | 轮询-(默认) | 开启一个计数器count,在while循环中遍历服务清单,取到服务后计数器会+1,连续10次取不到会报异常 |
WeightedResponseTimeRule | 权重 | 即根据响应时间来选择服务的实例,时间短则权重大,默认情况下每隔30秒会计算一次各个服务实例的权重 |
RetryRule | 重试-轮询 | 当轮询至某个实例没有响应时,会在超时时间内进行重试,超出时间会返回null |
BestAvailableRule | 优选策略(我自己取得名字) | 会过滤掉故障的实例,并找出并发请求数最小的一个,所以该策略的特性是选出最空闲的实例。 |
PredicateBasedRule | 过滤 | 先通过内部定义的一个过滤器过滤出一部分服务实例清单,然后再采用线性轮询的方式从过滤出来的结果中选取一个服务实例。 |
ZoneAvoidanceRule | 组合过滤 | 以ZoneAvoidancePredicate为主过滤条件和以AvailabilityPredicate为次过滤条件组成,过滤后继续采用线性轮询的方式 |