SpringCloud搭建基于Eureka服务中心的微服务体系

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/superyu1992/article/details/83340455

一、单体系统与微服务体系

在以往传统的企业系统架构中,所有的业务接口都被集中在同个单体应用中。在业务需求不庞大的情况下,这样的系统架构在开发、测试、部署时都还比较方便,但是随着企业的发展,更多的业务需求也随之而来,单体应用为了满足这些需求就必须增加相应的业务模块,单体应用就会显得越来越臃肿;由于单体应用的所有业务都运行在同一个系统进程中,即使我们只是修改了一个很小的功能,也需要将整个项目全量更新上线,进而导致影响其他功能;单体应用的架构和业务逻辑对所有参与的开发者都是开放的,这就带来了一定的风险,某个开发者的一个误操作就有可能影响整个系统。

基于以上几点,分布式的微服务体系应运而生,它将系统内的各个功能模块拆分成不同的服务,这些服务都可以独立部署和扩展;由于各服务都运行在各自的进程中,每个服务的更新或是中断都不会影响其他服务;不同的业务可以根据不同的需求去自定义技术平台、服务器配置、数据库配置等,从而避免出现“杀鸡用牛刀”等情况;开发者只需根据业务划分,维护自己负责的服务,降低了开发风险。

二、SpringCloud简介

SpringCloud是一个基于SpringBoot的微服务架构开发工具。他提供了微服务开发所需的配置管理、服务发现、断路器、智能路由、微代理、控制总线、全局锁、决策竞选、分布式会话和集群状态管理等组件。最重要的是,跟spring boot框架一起使用的话,会让你开发微服务架构的云服务非常好的方便。SpringBoot旨在简化创建产品级的 Spring 应用和服务,简化了配置文件,使用嵌入式web服务器,含有诸多开箱即用微服务功能。

三、核心结构分析

整个微服务体系主要由三个核心模块组成:Eureka服务注册中心、服务提供者、服务消费者。

Eureka服务注册中心:Eureka提供的服务端,用于注册、发现、

他们的逻辑关系如下图所示,稍后会结合具体实现,进行分析。

四、具体实现

1、创建Eureka服务注册中心:

1.1 创建SpringBoot工程

以idea为例,创建一个SpringBoot工程,在选择依赖的时候,在Cloud Discovery下找到EureKa Server并勾选,这样选择之后,idea就会帮助我们补充好pom中需要的依赖,其他一路next即可;

1.2 配置application.properties:

server.port:服务监听的端口
eureka.instance.hostname:eureka实例的主机名称;
eureka.client.register-with-eureka:是否将本项目作为服务注册到服务中心,由于本项目就是服务中心,所以就设置为false;
eureka.client.fetch-registry:是否需要检索服务,这里也不需要;
eureka.client.service-url.defaultZone:eureka服务中心的访问地址;
spring.application.name:eureka服务中心的应用名称;

server.port=1112

eureka.instance.hostname=localhost
eureka.client.register-with-eureka=false
eureka.client.fetch-registry=true
eureka.client.service-url.defaultZone=http://${eureka.instance.hostname}:${server.port}/eureka/

spring.application.name=eureka_server

1.3 设置Application,开启EurekaServer:

package com.eureka_center;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;

@SpringBootApplication
@EnableEurekaServer
public class EurekaCenterApplication {

	public static void main(String[] args) {
		SpringApplication.run(EurekaCenterApplication.class, args);
	}
}

设置完成后,运行项目,看到如下界面证明运行成功:

2、创建并注册服务提供者:

2.1 创建一个Spring Boot应用

可以直接通过IDE创建,也可以进入https://start.spring.io/进行创建;

2.2 配置pom.xml

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.service_provider</groupId>
	<artifactId>service_provider</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<packaging>jar</packaging>

	<name>service_provider</name>
	<description>service_provider for Spring Cloud</description>

	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>2.0.5.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>Finchley.SR1</spring-cloud.version>
	</properties>

	<dependencies>

		<!--全栈web开发模块,包含嵌入式Tomcat、SpringMVC-->
		<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>

		<!--Eureka服务端依赖-->
		<dependency>
			<groupId>org.springframework.cloud</groupId>
			<artifactId>spring-cloud-starter-eureka</artifactId>
			<version>1.3.6.RELEASE</version>
		</dependency>

	</dependencies>


	<!--Spring Cloud 依赖-->
	<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>

这里有一点要注意,就是SpringCloud的版本要与springboot相对应,我这里使用的SpringBoot的版本是2.0.5.RELEASE对应的SpringCloud版本是Finchley.SR1。(可以直接套用之前配置eureka服务中心的SpringCloud)

2.3 配置application.properties:

server.port=9001
spring.application.name=hello-service
eureka.client.service-url.defaultZone=http://localhost:1112/eureka/

2.4 新建一个RestController

DiscoveryClinet用于帮助客户端与eureka server互相协作:

1、向server注册服务实例;
2、向server服务租约;
3、服务关闭期间,向server取消租约;
4、查询服务实例列表;

这里创建了一个RestController,查询服务实例列表并打印所有服务,并且返回HelloWorld;

package com.service_provider.controller;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
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.RestController;

import java.util.List;


/**
 *
 * @author yuyan
 * @create 2018-10-23 14:31
 **/
@RestController
public class HelloController {

   private Logger logger = LoggerFactory.getLogger(this.getClass());

   @Autowired
   DiscoveryClient client;

   @RequestMapping("/hello")
   public String index(){
      for(String service:client.getServices()){
         List<ServiceInstance> services  = client.getInstances(service);
         for(ServiceInstance serviceInstance:services){
            logger.info("/hello, host:" + serviceInstance.getHost() + ", service_id:" + serviceInstance.getServiceId());
         }
      }

      return "Hello World";
   }

}

2.5 设置Application,通过EnableDiscoveryClient注解,让该应用注册成为Eureka客户端应用;

package com.service_provider;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;

@EnableDiscoveryClient
@SpringBootApplication
public class ServiceProviderApplication {

	public static void main(String[] args) {
		SpringApplication.run(ServiceProviderApplication.class, args);
	}
}

设置完成后,运行项目,运行成功后就可以在EurekaCenter的管理界面上,查看到服务信息:

3、创建服务消费者

3.1 创建一个Spring Boot应用

3.2 配置pom.xml:

同样,需要引入SpringCloud和Eureka服务端依赖,这里多引入了一个ribbon依赖,用于实现客户端的负载均衡,关于负载均衡,会在后面进行解释;

<?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.ribbon_consumer</groupId>
	<artifactId>ribbon_consumer</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<packaging>jar</packaging>

	<name>ribbon_consumer</name>
	<description>ribbon_consumer</description>

	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>2.0.5.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>Finchley.SR1</spring-cloud.version>
	</properties>

	<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>

		<dependency>
			<groupId>org.springframework.cloud</groupId>
			<artifactId>spring-cloud-starter-eureka</artifactId>
			<version>1.3.6.RELEASE</version>
		</dependency>


		<!--Finchley的SpringCloud不能使用这个-->
		<!--<dependency>-->
			<!--<groupId>org.springframework.cloud</groupId>-->
			<!--<artifactId>spring-cloud-starter-ribbon</artifactId>-->
		<!--</dependency>-->

		<dependency>
			<groupId>org.springframework.cloud</groupId>
			<artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
		</dependency>
		<!--<dependency>-->
			<!--<groupId>org.springframework.cloud</groupId>-->
			<!--<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>-->
		<!--</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>

3.3 配置application.properties:

server.port=9000
spring.application.name=consumer
eureka.client.service-url.defaultZone=http://localhost:1112/eureka/

3.4 配置Application主类:

与服务提供者类似,通过EnableDiscoveryClient注解,让服务消费者注册成为Eureka客户端应用,并且在该主类中创建RestTemplate的SpringBoot实例,通过LoadBalanced开启客户端负载均衡;

package com.service_consumer;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.web.client.RestTemplate;

@EnableDiscoveryClient
@SpringBootApplication
public class ServiceConsumerApplication {

	@Bean
	@LoadBalanced//开启客户端负载均衡
	RestTemplate restTemplate(){
		return new RestTemplate();
	}

	public static void main(String[] args) {
		SpringApplication.run(ServiceConsumerApplication.class, args);
	}
}

3.5 创建一个RestController,用来调用服务提供者的服务:

通过restTemplate以get方式调用服务名称为HELLO-SERVICE的hello接口,并且返回接口的结果;这里使用的是服务名,而不是具体的ip或是域名作为访问地址,服务名可以通过Eureka控制台获取,或者通过DiscoveryClient获得服务列表;

package com.service_consumer.controller;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
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.RestController;
import org.springframework.web.client.RestTemplate;

import java.util.List;

@RestController
public class ConsumerController {

    private Logger logger = LoggerFactory.getLogger(this.getClass());

    @Autowired
    RestTemplate restTemplate;

    @RequestMapping(value = "/hello_consumer", method = RequestMethod.GET)
    public String helloConsumer(){
       
        return restTemplate.getForEntity("http://HELLO-SERVICE/hello/",String.class).getBody();

    }

}


配置完成后,运行项目,运行成功后,打开Eureka服务控制台:

可以看到现在有两个应用,分别是一个消费者和一个提供者,现在访问localhost:9000/hello_consumer:

成功的返回了服务提供者的返回值:Hello World

至此,一个基于基于Eureka服务中心的微服务体系就搭建成功了!

猜你喜欢

转载自blog.csdn.net/superyu1992/article/details/83340455