带着问题去无疑是一种非常好的学习方法,所以在学习的开始,我的脑子立即冒出几个问题?
Spring cloud 是什么? 它能干什么?为什么要用它,它的优势在哪?
然后我百度了一下百度百科,百度百科:
Spring Cloud是一系列框架的有序集合。它利用Spring Boot的开发便利性巧妙地简化了分布式系统基础设施的开发,如服务发现注册、配置中心、消息总线、负载均衡、断路器、数据监控等,都可以用Spring Boot的开发风格做到一键启动和部署。Spring并没有重复制造轮子,它只是将目前各家公司开发的比较成熟、经得起实际考验的服务框架组合起来,通过Spring Boot风格进行再封装屏蔽掉了复杂的配置和实现原理,最终给开发者留出了一套简单易懂、易部署和易维护的分布式系统开发工具包。
从百度百科的定义中我看出,spring cloud不是单独的一个东西,它是一系列框架的一个组合,它是以spring boot为基础的,springboot我已经很熟悉了,这里不再多述,然后它能简化分布式系统的基础开发,至于什么是分布式系统,为什么要采用分布式开发,不是本篇文章的主题,稍后有时候再单独总结一下。Spring cloud没有重复制程轮子,只是将现有比较成熟的服务框架进行组合,开发起来更加简单易懂,部署、维护也更加方便,这就是它的优势。下面就将一点一点掀开spring cloud的神秘面纱,看看是否像传说中那么神奇。
服务的注册与发现:
这里用到了Spring cloud netflix 的eureka服务注册与发现模块。
建一个maven项目:serviceCenter,这是服务注册中心,所有服务都要在这里注册,所有的其他客户端调用都是从服务中心来找到需要的服务然后调用
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.0http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.gaox.serviceCenter</groupId>
<artifactId>serviceCenter</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>serviceCenter</name>
<description>Demo project for Spring Boot</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.10.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>
<spring-cloud.version>Edgware.SR2</spring-cloud.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-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>
eureka是一个高可用的组件,它没有后端缓存,每一个实例注册之后需要向注册中心发送心跳(因此可以在内存中完成),在默认情况下erureka server也是一个eureka client ,,通过eureka.client.registerWithEureka:false和fetchRegistry:false来表明自己是一个eureka serve
Application.properties:
#服务端口
server.port=8761
#服务名称
eureka.instance.hostname=serviceCenter
#禁止本身注册
eureka.client.register-with-eureka=false
#禁止本身注册
eureka.client.fetch-registry=false
#服务中心地址
eureka.client.service-url.defaultZone=http://${eureka.instance.hostname}:${server.port}/eureka/
启动一个服务注册中心,只需要一个注解@EnableEurekaServer,这个注解需要在springboot工程的启动application类上加
serviceCenterApplication.java
@SpringBootApplication
@EnableEurekaServer
public class ServiceCenterApplication {
public static void main(String[] args) {
SpringApplication.run(ServiceCenterApplication.class, args);
}
}
eureka server 是有界面的,启动工程,打开浏览器访问:
http://localhost:8761 ,界面如下:
再建一个maven项目:helloService,这里是具体的服务提供者,然后在服务的注册中心注册一下,其他的客户端就可以能过服务注册中心发现这个服务,并且调用它
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.gaox.helloService</groupId>
<artifactId>helloService</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>helloService</name>
<description>Demo project for Spring Boot</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.10.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>
<spring-cloud.version>Edgware.SR2</spring-cloud.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.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>
Application.properties:
server.port=8762
spring.application.name=helloService
eureka.client.service-url.defautZone=http://localhost:8761/eureka/
HelloServiceApplication.java:
package com.gaox.helloService;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
@SpringBootApplication
@RestController
@EnableEurekaClient
public class HelloServiceApplication {
public static void main(String[] args) {
SpringApplication.run(HelloServiceApplication.class, args);
}
@Value("${server.port}")
private String port;
@Value("${spring.application.name}")
private String hostname;
@RequestMapping("/hello")
public String hello(@RequestParam(name = "name") String name) {
return "你好," + name + "。我是" + hostname + ",端口是" + port;
}
}
需要指明spring.application.name,这个很重要,这在以后的服务与服务之间相互调用一般都是根据这个name 。
启动工程,打开http://localhost:8761 ,即eurekaserver 的网址,helloService已经注册进去了。
原有8762那个helloService服务不关闭,把端口改成8763,然后再启动一个服务你会发现同一个服务有两个实例,端口不一样