Spring Cloud 微服务框架之服务注册与发现

来源:互联网 发布:淘宝流量下跌 编辑:程序博客网 时间:2024/04/29 07:57

Spring Cloud介绍

Spring Cloud是一个相对比较新的微服务框架,2016才推出1.0的release版本. 虽然Spring Cloud时间最短, 但是相比Dubbo等RPC框架, Spring Cloud提供的全套的分布式系统解决方案。

Spring Cloud 为开发者提供了在分布式系统(配置管理,服务发现,熔断,路由,微代理,控制总线,一次性token,全居琐,leader选举,分布式session,集群状态)中快速构建的工具,使用Spring Cloud的开发者可以快速的启动服务或构建应用、同时能够快速和云平台资源进行对接。

微服务架构

微服务可以在“自己的程序”中运行,并通过“轻量级设备与HTTP型API进行沟通”。关键在于该服务可以在自己的程序中运行。通过这一点我们就可以将服务公开与微服务架构(在现有系统中分布一个API)区分开来。在服务公开中,许多服务都可以被内部独立进程所限制。如果其中任何一个服务需要增加某种功能,那么就必须缩小进程范围。在微服务架构中,只需要在特定的某种服务中增加所需功能,而不影响整体进程。
微服务不需要像普通服务那样成为一种独立的功能或者独立的资源。定义中称,微服务是需要与业务能力相匹配,这种说法完全正确。不幸的是,仍然意味着,如果能力模型粒度的设计是错误的,那么,我们就必须付出很多代价。如果你阅读了Fowler的整篇文章,你会发现,其中的指导建议是非常实用的。在决定将所有组件组合到一起时,开发人员需要非常确信这些组件都会有所改变,并且规模也会发生变化。服务粒度越粗,就越难以符合规定原则。服务粒度越细,就越能够灵活地降低变化和负载所带来的影响。然而,利弊之间的权衡过程是非常复杂的,我们要在配置和资金模型的基础上考虑到基础设施的成本问题。

服务注册与发现

接下来我们通过实际案例来看看如何使用Spring Cloud搭建服务注册与发现模块,案例中核心内容就是服务发现模块:Eureka

1、首先创建“服务注册中心”

(1)创建一个Maven工程,并在pom.xml中引入需要的依赖内容:

<parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>1.3.5.RELEASE</version><relativePath/></parent><properties><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding><java.version>1.7</java.version></properties><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency><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>Brixton.RELEASE</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>
(2)通过@EnableEurekaServer注解启动一个服务注册中心提供给其他应用进行对话。这一步非常的简单,只需要在一个普通的Spring Boot应用中添加这个注解就能开启此功能,创建一个Application.java,如下所示:

package com.wys;import org.springframework.boot.autoconfigure.SpringBootApplication;import org.springframework.boot.builder.SpringApplicationBuilder;import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;@EnableEurekaServer@SpringBootApplicationpublic class Application {public static void main(String[] args) {new SpringApplicationBuilder(Application.class).web(true).run(args);}}
(3)在默认设置下,该服务注册中心也会将自己作为客户端来尝试注册它自己,所以我们需要禁用它的客户端注册行为,只需要在application.properties中问增加如下配置:
server.port=1111#eureka.instance.hostname=localhosteureka.client.register-with-eureka=falseeureka.client.fetch-registry=falseeureka.client.serviceUrl.defaultZone=http://localhost:${server.port}/eureka/
至此,简单的服务注册就搭建好了,项目整体结构如下:


现在启动工程(Application.java),访问:http://localhost:1111/     (注意这里的1111是自己在application.properties文件中设置的端口号)

此时,可以看到下面的页面,其中还没有发现任何服务


该工程可参考:eureka-server

(4)创建“服务提供方”

接下来我们创建提供服务的客户端,并向服务注册中心注册自己。

假设我们有一个提供计算功能的微服务模块,我们实现一个RESTful API,通过传入两个参数a和b,最后返回a + b的结果。

首先,创建一个Maven工程,在pom.xml文件中加入依赖,如下所示。

<parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>1.3.5.RELEASE</version><relativePath/></parent><properties><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding><java.version>1.7</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-test</artifactId><scope>test</scope></dependency></dependencies><dependencyManagement><dependencies><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-dependencies</artifactId><version>Brixton.RELEASE</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>
(5)实现/add请求处理接口,通过DiscoveryClient对象,在日志中打印出服务实例的相关内容

package com.wys.web;import org.apache.log4j.Logger;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.cloud.client.ServiceInstance;import org.springframework.cloud.client.discovery.DiscoveryClient;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RequestMethod;import org.springframework.web.bind.annotation.RequestParam;import org.springframework.web.bind.annotation.RestController;@RestControllerpublic class ComputeController {private final Logger logger=Logger.getLogger(getClass());@Autowiredprivate DiscoveryClient client;@RequestMapping(value="/add",method=RequestMethod.GET)public Integer add(@RequestParam Integer a,@RequestParam Integer b){ServiceInstance instance=client.getLocalServiceInstance();Integer r=a+b;logger.info("/add, host:" + instance.getHost() + ", service_id:" + instance.getServiceId() + ", result:" + r);return r;}}
(6)在主类中通过加上@EnableDiscoveryClient注解,该注解能激活Eureka中的DiscoveryClient实现,才能实现Controller中对服务信息的输出。
package com.wys;import org.springframework.boot.autoconfigure.SpringBootApplication;import org.springframework.boot.builder.SpringApplicationBuilder;import org.springframework.cloud.client.discovery.EnableDiscoveryClient;@EnableDiscoveryClient@SpringBootApplicationpublic class ComputeServiceApplication {public static void main(String[] args) {new SpringApplicationBuilder(ComputeServiceApplication.class).web(true).run(args);}}
(7)完成了服务内容的实现之后,再继续对application.properties做一些配置工作,具体如下:

spring.application.name=compute-serviceserver.port=2222eureka.client.serviceUrl.defaultZone=http://localhost:1111/eureka/
通过spring.application.name属性,我们可以指定微服务的名称后续在调用的时候只需要使用该名称就可以进行服务的访问。
eureka.client.serviceUrl.defaultZone属性对应服务注册中心的配置内容,指定服务注册中心的位置。
为了在本机上测试区分服务提供方和服务注册中心,使用server.port属性可以设置不同的端口。

至此,“服务提供方”已经创建好了,整体项目结构如下:

启动该工程之前,先启动刚刚创建的服务注册中心(eureka-server中的Application.java)

访问:http://localhost:1111/    可以看到,我们定义的服务被注册了。


该工程可参考:compute-service

0 0