今天开始去搞SpringCloud,它经常被拿来和Dubbo对比,之前学习Dubbo的时候没有记录在博客上,等把SpringCloud整理的差不多了,我在把Dubbo的笔记整理到博客上,学习SpringCloud之前,肯定要先了解一下这玩意是个什么东西。先来一段花里胡哨切看不懂的文字。
spring cloud 是一系列框架的集合。它利用 spring boot 的开发便利性巧妙地简化了分布式系统基础设施的开发,如服务发现注册、配置中心、消息总线、负载均衡、断路器、数据监控等,都可以用 spring boot 的开发风格做到一键启动和部署。spring cloud 并没有重复制造轮子,它只是将目前各家公司开发的比较成熟、经得起实际考验的服务框架组合起来,通过 spring boot 风格进行再封装屏蔽掉了复杂的配置和实现原理,最终给开发者留出了一套简单易懂、易部署和易维护的分布式系统开发工具包。
我看完就一个感觉,SpringCloud是一锅大杂烩,而且是优秀的大杂烩。其中提供了很多组件,对每个组件都进行了封装,简化了开发。反正就是十分优秀,我还特地去他的中文官网看了看。还挺多,自己看吧。SpringCloud中文文档
介绍就介绍到这里吧,接下来我们就来说说如何使用它
SpringCould的服务注册依赖于一个Eureka客户端,在SpringCloud里边被叫做发现服务器和客户端,听着十分难以理解,他的和zookeeper注册中心类似,我就把它理解为是对服务进行统一管理的一个服务器了。首先我们要搭建这个服务器,才能实现服务的注册与调用,就像Dubbo的使用必须依赖于像zookeeper一样的注册中心。接下来说如何搭建。
刚看到这里的时候,我还十分不理解,因为在使用Dubbo的时候,zookeeper注册中心是需要在Linux服务器上安装的,而SpringCloud里边的注册中心是一个java项目,该项目之后会运行在服务器的对服务进行统一的管理。我们先创建一下子。这里就创建SpringBoot项目了,是一个java项目,不也是web项目,由于我已经创建过了,所以这里只是演示,忽略报错。如下图:
<!-- 统一版本号 -->
<properties>
<java.version>1.8</java.version>
<spring-cloud.version>Greenwich.SR1</spring-cloud.version>
</properties>
<dependencies>
<!-- eureka-server依赖 -->
<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>
<dependencyManagement>
<dependencies>
<!-- 引入springcloud项目依赖 -->
<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>
<!-- maven打包插件 -->
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
这每个必要的配置我都会注释,说明其作用。除了我写的这些配置之外,在SpringCloud中文文档官网中还说明了其他的一些配置,开头我已经留下了网址,感兴趣的可以去研究。另外,yml文件是以缩进来区分代码块的,所以如果复制的话,要检查缩进格式。
#配置项目名
spring:
application:
name: eureka-server
#配置端口号
server:
port: 2001
#配置eureka服务器
eureka:
server:
####关闭自我保护机制
enable-self-preservation: false
client:
####不向自身注册
register-with-eureka: false
####不向自身拉取注册信息
fetch-registry: false
service-url:
#覆盖默认的URL,如果不覆盖的,他们频繁的请求一个默认的URl,感兴趣的可以翻源码,这里就不贴出来了
defaultZone: http://127.0.0.1:2001/eureka/
在前面的工作都做完之后,我们要在SpringBoot主启动类上,添加@EnableEurekaServer注解,目的是用于启动Eureka注册中心。如下图:
到这里,我们的Eureka服务器就搭建完成了。接下来要做的工作就是测试一下,启动Eureka项目,访问项目,出现如下界面,说明搭建成功。
这里创建的是一个web项目,所以我们需要导入springmvc的web依赖。除了这些,还要导入eureka的客户端依赖。
<!-- 引入eureka依赖 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>
spring-cloud-starter-netflix-eureka-client
</artifactId>
<version>2.1.1.RELEASE</version>
</dependency>
#配置项目名
spring:
application:
name: springcloud-01
#配置端口号
server:
port: 8001
eureka:
client:
#### 这里就是我们刚才Eureka服务器未来运行的URl地址。
service-url:
defaultZone: http://127.0.0.1:2001/eureka/
我们在自己的项目中编写Service接口和接口的实现类,这些接口就是对外暴露的服务。
package com.company.service;
public interface TestService {
String testSpringCloud();
}
package com.company.service.impl;
import org.springframework.stereotype.Service;
import com.company.service.TestService;
@Service(value = "TestServiceImpl")
public class TestServiceImpl implements TestService {
@Override
public String testSpringCloud() {
return "我是springcloud-2的大哥,我叫springcloud-1,这是我的远程调用的方法。";
}
}
package com.company.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.company.service.TestService;
@RestController
@RequestMapping(value = "/test/")
@CrossOrigin(origins = "*",maxAge = 3600)
public class TestController {
@Autowired
private TestService testService;
@RequestMapping(value = "sp")
public String testSpringCloud() {
return testService.testSpringCloud();
}
}
同样,在前面的工作都做完之后,我们要在SpringBoot主启动类上,添加 @EnableDiscoveryClient注解,目的是用于将我们自己写的Service服务注册到Eureka的服务器。如下图:
我们分别启动Eureka服务器和我们自己的项目,启动不分先后顺序,如果控制台报错,不用管,因为Eureka注册很慢,他会不断尝试注册,我们打开Eureka的注册中心页面,如果我们看到自己的服务,说明我们的服务注册成功,如下图:
前面的工作,我们完成了服务的Eureka服务器的搭建,服务的发布,现在我们要调用服务。步骤和服务提供者一样。
这里创建的是一个web项目,所以我们需要导入springmvc的web依赖。这里就不需要调入其他依赖了。如果是想把这个项目当做服务注册到Eureka中,也要到Eureka依赖。
#配置项目名
spring:
application:
name: springcloud-2
#配置端口号
server:
port: 8002
在这里要说明的一点是,SpringCloud中,是基于Http的远程方法调用,所以,才会需要我们编写Controller,因为我们需要通过SpringMVC来提供映射地址,我们使用RestTemplate通过这个地址调用到对应的远程方法,所以服务提供方在没有向Eureka注册中心注册服务时,我们一样可以调用到远程方法,所以两者没有必然联系。当时被这个搞懵了。既然是基于http的远程方法调用,为什么还要注册。我的理解是,注册是为了服务的同意管理,注册中心可以向服务消费者返回服务提供者的地址信息和端口信息,服务消费者可以在注册中心拿到想要的信息之后,就可以通过RestTemplate来进行远程方法调用。这个不像Dubbo,Dubbo是基于RPC的远程方法调用,服务如果不在zookeeper注册中心注册的话,是无法调用到对应的远程方法的。
package com.company;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
@RestController
@RequestMapping(value = "/test/")
@CrossOrigin(origins = "*",maxAge = 3600)
public class TestController {
@Autowired
private RestTemplate rt;
@RequestMapping(value = "consumer")
public String testSpringCloud() {
String result = rt.getForObject("http://localhost:8001/test/sp", String.class);
return result;
}
}
现在我们就同时启动三个项目,然后测试一下。我们通过消费者项目,来访问服务提供者。浏览器输入我们消费者的Controller方法的映射地址。如下图,访问成功。
感兴趣可以试一下,把服务提供方项目里的Eureka个移除,只启动,服务消费方和提供方两个项目,一样可以访问到方法。不过总感觉很别扭,难以理解。