springcloud基础搭建——生产者、注册中心、网关

版权声明:本文为博主原创文章,如需转载请注明出处 https://blog.csdn.net/linghuanxu/article/details/88937844

背景

说实话,一直以来都说有空搭一套springcloud,一直都没腾出功夫来。当然了,工作确实忙,也有不少东西要研究,就这么耽误下来了。不过,这里面也有springcloud本身的问题。基本的demo都要起几个进程才能测试,对于懒得建项目码代码的我来说,就一直在推迟了。知道最近,打算在公司推了,才真的下定决心搞了。
  上面呢,基本都是废话,后面说干的哈。为什么要用springcloud?这个问题,其实很庞大。我的思路是这样的。其实,一直以来,我都是鼓励在产品中,应用领域驱动设计业务,迭代产品。但是,一直以来的开发方法都很笨重,早先的理论还在soa,但其实落地也有不少偏差。比如,之前项目的搭建是若干项目提供服务接口,然后由一个出口项目集成各个接口,同时解决会话授权等问题,这个项目一般来说写的是jsp。后来因为一次项目经验,摸到了前后端分离已经成熟,所以更加倾向于前端直接写html,但是聚合api就成了难事,也想过拿nginx一个一个代理出去。但是始终觉得,建项目也很重,通信也很重。早先就认识dubbo,但是对于接口文件的依赖和各种配置,实在是,看似解耦,实际上似乎又变得很复杂。
  最后,认识了springboot,解决了建项目重的问题,同时还解决了配置复杂的问题。然后,注册中心虽然要自己建立项目,但是好在各种监控一应俱全,管理难度下降。同时,提供了聚合的网关,搭到集群里就可以自动代理api了。似乎,事情本来就该这个样子。好了,思路说到这里,后面开始具体的。
  这次的搭建要形成这样一个demo,一个服务提供者,一个注册中心,一个网关,我们可以通过网关访问到服务提供者的接口。

搭建

注册中心

springcloud默认没有用zookeeper做注册中心而是用的eureka。说实话,没查这玩意,就知道是可以用来做注册中心。可以在别的注册中心注册自己来传递注册信息,本身可以查看注册状态,别的就不知道了。项目本身也很简单,其实就三个文件。一个StartApplication类,是启动类,实际有效的,也就是一个注解@EnableEurekaServer。下面是文件内容:

@SpringBootApplication
@EnableEurekaServer
public class StartApplication {

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

当然了,我们还要看下引入了什么依赖,pom文件如下:

<?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>net.fblock.springcloud</groupId>
    <artifactId>regcenter</artifactId>
    <version>1.0.0-SNAPSHOT</version>

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

        <spring.version>4.3.12.RELEASE</spring.version>
        <springboot.version>1.5.8.RELEASE</springboot.version>
    </properties>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.5.8.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>

    <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-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>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>2.3.2</version>
                <configuration>
                    <source>${java.version}</source>
                    <target>${java.version}</target>
                </configuration>
            </plugin>
        </plugins>
    </build>


</project>

我们可以看到,实际上多引入的就是spring-cloud-starter-eureka-server这么一个依赖,配置文件也很简单,主要就是声明端口,服务名,以及一些基本的配置:

server:
  port: 9000
eureka:
  instance:
    hostname: registration-center
  client:
    registerWithEureka: false
    fetchRegistry: false

registerWithEureka为false是不把自己注册到注册中心,说是可以自己注册到自己上面,同时,集群也是用这个注册的思路搭建的。fetchRegistry是否获取注册服务器上的注册信息,默认是true,不知道为什么启动不起来,就设置成了false。
  这样,这个项目就可以启动了,访问http://localhost:9000 可以看到注册中心的相关信息,也可以看到当前注册了哪些节点。

网关

网关的搭建和注册中心是差不多的,所以我们就先搭建它了。还是只有一个代码文件:

@SpringBootApplication
@EnableZuulProxy
@EnableDiscoveryClient
public class StartApplication {

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

}

实际生效的代码是这么两个注解:@EnableZuulProxy,这个的意思是启用zuul网关;@EnableDiscoveryClient,这个的意思是启用自动发现客户端,用来发现注册中心的服务。下面我们看pom文件:

<?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>net.fblock.springcloud</groupId>
    <artifactId>gateway</artifactId>
    <version>1.0.0-SNAPSHOT</version>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.5.9.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>

        <spring.version>4.3.12.RELEASE</spring.version>
        <springboot.version>1.5.8.RELEASE</springboot.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-eureka</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-zuul</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-zipkin</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-feign</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-hystrix</artifactId>
        </dependency>

        <!--actuator是spring boot提供的对应用系统的自省和监控的集成功能,可以对应用系统进行配置查看、相关功能统计等-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>

        <dependency	>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-config</artifactId>
        </dependency>
        <dependency	>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-netflix-eureka-client</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.retry</groupId>
            <artifactId>spring-retry</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-aop</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>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>2.3.2</version>
                <configuration>
                    <source>${java.version}</source>
                    <target>${java.version}</target>
                </configuration>
            </plugin>
        </plugins>
    </build>

</project>

这里看依赖项是有点多的,这是因为我是抄的别人的例子,暂时还没有时间梳理其中的具体依赖关系。总的来说,就是这么几个方面的东西:

  • 首先这个项目得支持springboot,可以启动起来
  • 然后这个项目得是个springcloud的服务,能够搭载到注册中心区,自动发现服务,自动提供服务。
  • 最后,得拥有自己的网关的功能

大家先按照上面说的自己识别下依赖吧,有空我整理出来再补回来。
  最后,依然是配置文件,先看吧:

eureka:
  client:
    serviceUrl:
      defaultZone: http://localhost:9000/eureka   #网关连接的注册中心地址,host或者ip,多个用,隔开
server:
  port: 9001        #此网关对外提供的端口号

spring:
  application:
    name: gateway     #网关服务名,每个网关一致gateway-server

配置文件的信息也大概就是这么几方面。首先是,声明自己的注册中心在哪,然后是自己占用的端口号,最后是自己的服务名称。服务名称和注册中心地址是每个springcloud服务都需要声明的,当然,端口号也应该是每个服务必须声明的。这里有个问题,我没有声明怎么对外提供服务,那我该怎么访问我的服务呢?后面我们搭完demo服务再回来说这个话题。

demo_service

为了可以测试,我搭建了一个样例的service服务。我们就只提供一个ping接口,返回pong。其实服务本身就是一个springmvc的项目,唯一不同的是我们在StartApplication上声明了@EnableDiscoveryClient注解,就可以搭载自己到注册中心了,下面我就直接上代码了,StartApplication:

@SpringBootApplication
@EnableDiscoveryClient
public class StartApplication {

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

DemoController

@RestController
@RequestMapping("/demo")
public class DemoController {

	@RequestMapping("/ping")
	public Map<String,String> ping(){
		Map<String,String> data=new HashMap<>();
		data.put("ping","pong");
		return data;
	}

}

pom文件:

<?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>net.fblock.springcloud</groupId>
    <artifactId>demo.service</artifactId>
    <version>1.0.0-SNAPSHOT</version>

    <properties>
        <spring.version>4.3.12.RELEASE</spring.version>
        <springboot.version>1.5.8.RELEASE</springboot.version>
        <jdk.version>1.8</jdk.version>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <spring-cloud.version>Edgware.SR2</spring-cloud.version>
    </properties>

    <dependencies>
        <dependency>
            <!-- Import dependency management from Spring Boot -->
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-dependencies</artifactId>
            <version>${springboot.version}</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <version>${springboot.version}</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
            <version>${springboot.version}</version>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
        </dependency>

        <!--dev tool start-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <version>${springboot.version}</version>
            <optional>true</optional>
            <scope>true</scope>
        </dependency>
        <!--dev tool end-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-eureka-server</artifactId>
            <version>1.4.3.RELEASE</version>
        </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>
        <finalName>demo-service</finalName>
        <!--
            将所有文件打入jar包,否则src/main/java下的xml文件将不会被打入jar包
            但是已加入该配置后,需要加入所有的复制文件的配置,否则,resource将会认为不进行复制
        -->
        <resources>
            <resource>
                <directory>src/main/java</directory>
                <includes>
                    <include>**/*.xml</include>
                </includes>
                <filtering>false</filtering>
            </resource>
            <resource>
                <directory>src/main/resources</directory>
                <includes>
                    <include>**/*.properties</include>
                    <include>**/*.xml</include>
                </includes>
                <filtering>false</filtering>
            </resource>
            <resource>
                <directory>src/main/resources</directory>
                <includes>
                    <include>**/*.properties</include>
                    <include>**/*.yml</include>
                </includes>
                <filtering>false</filtering>
            </resource>
            <resource>
                <directory>src/main/webapp</directory>
                <includes>
                    <include>**/*.*</include>
                </includes>
                <filtering>false</filtering>
            </resource>
        </resources>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <version>${springboot.version}</version>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>2.3.2</version>
                <configuration>
                    <source>${jdk.version}</source>
                    <target>${jdk.version}</target>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <version>${springboot.version}</version>
                <configuration>
                    <!--fork : 如果没有该项配置,肯呢个devtools不会起作用,即应用不会restart -->
                    <fork>true</fork>
                </configuration>
                <executions>
                    <execution>
                        <goals>
                            <goal>repackage</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <fork>true</fork>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-war-plugin</artifactId>
                <version>3.0.0</version>
                <configuration>
                    <failOnMissingWebXml>false</failOnMissingWebXml>
                </configuration>
            </plugin>
        </plugins>
    </build>

</project>

这个有点长,因为build的内容是拷贝我现在的springboot项目的,解决了一些常见的问题。重点看依赖吧。配置文件如下:

server:
  port: 9002
spring:
  application:
    name: demo_service
  data:
    mongodb:
      uri: mongodb://192.168.254.154:27017
      Database: core-test

eureka:
  client:
    serviceUrl:
      defaultZone: http://localhost:9000/eureka/

可以看到也是声明了端口号、注册中心地址、服务名称,这里的mongo的配置是为了解决找不到mongo相关的报错,也可以在启动注解中排除进行解决。

说明

上面的代码完了,这里集中进行说明吧。前面抛出的问题,没有配置路由规则,我们将会如何。答案是,网关有默认规则,是在你的uri前面加上服务id,也就是你配的servicename。比如,我们现在提供的ping接口的访问地址就是:http://localhost:9001/demo_service/demo/ping 不过,我们也可以具体配置,如下:

zuul:
  routes:
    demo_service:
      path: /test/**
      serviceId: demo_service

这就是说,serviceId会配路由到/test/** 下,我们的访问地址就变成了:http://localhost:9001/test/demo/ping
  大概就是这样了。

补充说明

调试的时候发现,进入service调试,会导致超时,从而网关直接返回异常,超时时间是需要配置的。同时,注册中心的集群方案,也是有待尝试的。期待后续的进展吧。
  相关的样例代码我放在https://gitee.com/naturetrible/ntbrick.demo 的springcloud文件夹中了,有兴趣的可以下下来玩玩。

猜你喜欢

转载自blog.csdn.net/linghuanxu/article/details/88937844