Springcloud使用入门

Springcloud是一款微服务框架,它基于Springboot,可以使用它用来管理纵向拆分的项目,将一个个的小项目变成微服务。下面简单的搭建一个微服务,使用eureka组件实现注册中心,使用ribbon组件实现微服务调用,使用zuul网关实现真实服务地址和访问地址的分离,其他技术后续补充。

springcloud和nginx

前面学习过nginx,它除了可以实现动静分离,还可以实现负载均衡,即可以将项目做成分布式tomcat集群,前端访问可以随机或者按照权重值访问后端服务。但是nginx有一个小缺点,如果单台服务器出现问题、或者需要添加服务器,需要修改conf.xml配置文件,或某台服务器出现问题如何容错等,ngnix是无法实现。简单来说它缺少管理者的因子,需要人为‘‘介入‘‘,在这种情况下,springcloud就可以弥补nginx的不足,它不仅仅可以实现分布式,负载均衡,并且对微服务有管理、容错、监听的能力。

springcloud

springcloud是spring家族的一员,它是一个微服务框架,用在大型分布式应用的开发,官网:https://spring.io/projects/spring-cloud,除了springcloud外,其他比较出名的微服务框架还有dubbo。

如果一个项目比较小,直接使用springboot,或者ssm做成单体项目就可以,但是如果一个项目比较大,就需要考虑到拆分,比较常见的就是横向拆分和纵向拆分。

(1)纵向拆分:大项目分成很多小项目,如电商网站的登录注册系统、商品系统、秒杀系统、搜索系统、购物车系统等,都是拆分后的小项目,这就是纵向拆分。

(2)横向拆分:一个纵向拆分后的项目,也可以继续拆分,如有人专门做控制层,有人做业务层,这就是横向拆分。

springcloud是如何对拆分后的项目进行管理的呢,这就需要用到它的关键组件,这里暂时先记录eureka、ribbon和zuul三种组件,其他组件如config、feign和hystrix后续单独补充。

(1)eureka:服务治理组件,利用它的注册和发现机制,实现整体微服务的管理,提供其他服务注册,并可以发现其他服务,springcloud只提供了一种这种治理组件。

(2)ribbon:通过eureka发现机制,可以负载均衡、随机或者根据权重来调用其他提供服务的组件。

(3)zuul:网关组件,唯一对外暴露接口地址的组件,实现外界访问地址和内部请求地址的分离,对外影藏了真实的地址。

下面使用一下这几个组件。

eureka

整个springcloud的核心组件之一,它就像一个‘‘管理者‘‘,利用自己的注册和发现的能力,来管理着一批注册在它身上的微服务。即其他服务可以注册在eureka注册中心,它管理着一批这样的已经注册的微服务,并对外提供服务,同时注册中心会将其他服务注册的信息保存到本地,通过定时更新来维护和其他服务的关系。简单来说注册中心就像‘‘工商局‘‘,各种公司之类的服务提供者都在这里注册,完了就可以对外提供服务了。

a.搭建eureka注册中心

使用IDEA,搭建一个eureka注册中心,搭建是基于springboot,需要利用springboot的自动配置和‘约定大于配置‘的特点,来配合springcloud简化搭建过程,注意两者版本的兼容,可以参考文末博客。

(1)pom文件导入springboot父pom、以及springcloud依赖。

<?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.boe</groupId>
  <artifactId>Eureka-server01</artifactId>
  <version>1.0-SNAPSHOT</version>

  <name>Eureka-server01</name>
  <!-- FIXME change it to the project‘s website -->
  <url>http://www.example.com</url>

  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <maven.compiler.source>1.7</maven.compiler.source>
    <maven.compiler.target>1.7</maven.compiler.target>
  </properties>

  <!--使用springboot的资源,结构特性。另外使用springcloud的所有依赖环境-->

  <!-- 基于springboot,继承springboot-parent,引入springboot的父pom文件 -->
  <parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <!--1.5.9是稳定版本-->
    <version>1.5.9.RELEASE</version>
  </parent>

  <!--导入springcloud的父pom资源,声明式依赖,子工程手动导入时就导包,不导入就不导入包-->
  <dependencyManagement>
    <dependencies>
      <!--导入springcloud-->
      <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-dependencies</artifactId>
        <version>Edgware.RELEASE</version>
        <!--注意通过坐标找到的spring-cloud-dependencies-Edgware.RELEASE.pom文件中,打包方式为pom,因此需要这里type为pom-->
        <type>pom</type>
        <!--maven scope方式常用有很多种,默认为compile,还有test、provided、system等-->
        <scope>import</scope>
      </dependency>

    </dependencies>
  </dependencyManagement>

  <!--以上两步,完成继承父springboot pom依赖,并导入springcloud的依赖管理-->

  <dependencies>

    <!--引入eureka注册中心的依赖-->
    <dependency>
      <groupId>org.springframework.cloud</groupId>
      <artifactId>spring-cloud-starter-eureka-server</artifactId>
      <!--建议使用下面的artifactId-->
      <!--<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>-->
    </dependency>

    <!-- spring-boot-starter-web 已经在eureka-server中传递,因此这里不需要配置springboot的starter-web-->

    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>3.8.1</version>
      <scope>test</scope>
    </dependency>
  </dependencies>

  <build>
    <plugins>
      <!--springboot运行jar包的插件,可以直接使用java -jar jar包名来运行springboot-->
      <plugin>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-maven-plugin</artifactId>
      </plugin>

      <!--指定jar包运行的main class-->
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-jar-plugin</artifactId>
        <!--<configuration>-->
          <!--<archive>-->
            <!--<manifest>-->
              <!--<addClasspath>true</addClasspath>-->
              <!--<mainClass>com.StarterEurekaServer</mainClass> &lt;!&ndash; 此处为主入口&ndash;&gt;-->
            <!--</manifest>-->
          <!--</archive>-->
        <!--</configuration>-->
      </plugin>

    </plugins>
  </build>

</project>

(2)资源目录下添加application.properties文件,添加服务端口、服务名、注册eureka中心地址等信息。

# 端口
server.port=8088
# 客户端通过ip底层注册
# eureka.client.prefer-ip-address=true
eureka.client.preferIpAddress=true
#暂时先关闭,当前注册中心作为客户端
# 在注册中心本身,使得具有注册和发现的能力,如果要实现HA,需要改成true,这样就会访问注册中心的接口
eureka.client.regist-with-eureka=false
# 关闭发现抓取注册信息的能力
eureka.client.fetch-registry=false
# 注册中心的地址,http请求的接口
eureka.client.serviceUrl.defaultZone=http://localhost:8088/eureka

# 当前工程提供一个服务名称,相同功能的工程创建集群,都是一个名称,以当前服务名为key保存在当前服务的所有节点信息的map对象中
# 如果是同一个name,就可以创建HA高可用
spring.application.name=eureka-server

# 可以关闭自我保护,没有收到续约,就从注册中心剔除服务
# eureka.server.enable-self-preservation=false

(3)写一个启动类,来启动注册中心,需要使用@EnableEurekaServer注解,来表名启动的是一个注册中心服务类。

package com;

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

/**
 * eureka server启动类
 */
@SpringBootApplication
@EnableEurekaServer
public class StarterEurekaServer {
    public static void main(String[] args) {
        SpringApplication.run(StarterEurekaServer.class,args);
        System.out.println("I am eureka server01");
    }
}

(4)启动后,访问注册中心地址localhost:8088,就可以查看注册中心注册的实例,这里有一个就是eureka服务自己本身,以后如果有注册的服务,都能在这里查看。

b.搭建一个微服务并注册

Eureka注册中心搭建起来后,接下里搭建一个微服务并注册在Eureka注册中心,并使用它提供的服务。

(1)pom文件与上面类似,这次搭建的是服务提供者,因此引入eureka客户端依赖(spring-cloud-starter-eureka)就可以。

<?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.boe</groupId>
  <artifactId>Client01</artifactId>
  <version>1.0-SNAPSHOT</version>

  <name>Client01</name>
  <!-- FIXME change it to the project‘s website -->
  <url>http://www.example.com</url>

  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <maven.compiler.source>1.7</maven.compiler.source>
    <maven.compiler.target>1.7</maven.compiler.target>
  </properties>

  <!--使用springboot的资源,结构特性。另外使用springcloud的所有依赖环境-->

  <!-- 基于springboot,继承springboot-parent,引入springboot的父pom文件 -->
  <parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>1.5.9.RELEASE</version>
  </parent>

  <!--导入springcloud的父pom资源-->
  <dependencyManagement>
    <dependencies>
      <!--导入springcloud-->
      <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-dependencies</artifactId>
        <version>Edgware.RELEASE</version>
        <!--注意通过坐标找到的spring-cloud-dependencies-Edgware.RELEASE.pom文件中,打包方式为pom,因此需要这里type为pom-->
        <type>pom</type>
        <scope>import</scope>
      </dependency>

    </dependencies>
  </dependencyManagement>

  <!--以上两步,完成继承父springboot pom依赖,并导入springcloud的依赖-->

  <dependencies>

    <!--引入eureka客户端依赖-->
    <dependency>
      <groupId>org.springframework.cloud</groupId>
      <artifactId>spring-cloud-starter-eureka</artifactId>
    </dependency>

    <!-- spring-boot-starter-web 已经在eureka-server中传递,因此这里不需要配置springboot的starter-web-->

    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>3.8.1</version>
      <scope>test</scope>
    </dependency>
  </dependencies>

  <build>
    <plugins>
      <!--springboot运行jar包的插件-->
      <plugin>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-maven-plugin</artifactId>
      </plugin>
    </plugins>
  </build>

</project>

(2)application.properties文件指定服务的端口号、服务名以及注册的中心地址url等信息。

# 客户端端口
server.port=9088

# 客户端通过ip底层注册
# eureka.client.prefer-ip-address=true
eureka.client.preferIpAddress=true

# eureka-client的注册,和发现功能需设置为true,默认为true,也可以不用设置
eureka.client.regist-with-eureka=true
# 发现抓取注册信息的内容
eureka.client.fetch-registry=true

# 定义服务名称
spring.application.name=service-hi

# 注册中心的地址
eureka.client.serviceUrl.defaultZone=http://localhost:8088/eureka

(3)写一个启动类,类似注册中心的启动类,只是注解需要修改成@EnableEurekaClient,这样的服务只有注册和发现的能力,不具备管理的能力。

package com;

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

/**
 * Eureka client服务提供者启动类
 */
@SpringBootApplication
@EnableEurekaClient
public class StarterEurekaClient {
    public static void main(String[] args) {
        SpringApplication.run(StarterEurekaClient.class,args);
        System.out.println("I am client01");
    }
}

(4)写个controller层的测试类,访问这个地址可以返回信息,如果能正常访问到,说明注册后的服务能正常使用。

package com.boe.Controller;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class MyController {
    //可以通过@Value注解,获取application.properties里的参数
    @Value("${server.port}")
    private String port;

    //写一个测试方法
    @RequestMapping("hello")
    public String test(String name){
        return "I am "+name+", and I come form "+port;
    }

}

(5)访问发现可以正常返回测试信息,并且注册中心页面也增添了一条注册信息,这样就实现了微服务的注册并提供服务的功能。

c.高可用eureka注册中心

高可用是分布式集群必不可少的一个特点,当其中一个节点宕机后,不影响整体的功能。eureka注册中心不仅对外可以提供服务注册,同时自己也作为注册微服务,可以注册在另外一台eureka注册中心,利用这个特点可以配置eureka高可用集群,这里配置3台eureka注册中心,实现集群HA服务。

eureka01注册到eureka02和eureka03,其他依次类推,这样完成注册后,每个eureka服务中心从对方抓得到的服务map信息就一致了,因为服务名一致,会纳入一个服务来管理,实现HA高可用。

想实现如上高可用,在IDEA当前工程下再添加两个Module,再修改application.properties文件 ,就可以实现,以eureka server01为例,需修改eureka.client.regist-with-eureka=true,使其具备注册的能力,同时修改eureka.client.fetch-registry=true,使其具备发现抓取注册的能力。另外eureka.client.serviceUrl.defaultZone写另外两台注册中心的地址,这样三台启动后就可以实现高可用。

# 端口
server.port=8088
# 客户端通过ip底层注册
# eureka.client.prefer-ip-address=true
eureka.client.preferIpAddress=true
#暂时先关闭,当前注册中心作为客户端
# 在注册中心本身,使得具有注册和发现的能力,如果要实现HA,需要改成true,这样就会访问注册中心的接口
eureka.client.regist-with-eureka=true
# 关闭发现抓取注册信息的内容
eureka.client.fetch-registry=true
# 注册中心的地址,http请求的接口,发现另外一个server的端口,实现HA高可用
eureka.client.serviceUrl.defaultZone=http://localhost:8089/eureka,http://localhost:8090/eureka

# 当前工程提供一个服务名称,相同功能的工程创建集群,都是一个名称,以当前服务名为key保存在当前服务的所有节点信息的map对象中
# 如果是同一个name,就可以创建HA高可用
spring.application.name=eureka-server

# 可以关闭自我保护,没有收到续约,就剔除服务
# eureka.server.enable-self-preservation=false

刚开始启动由于先后顺序,控制台会报错,这是正常的,因为先启动的服务可能找不到另外两台的(还在启动中),导致连接拒绝,以及找不到server的报错。

修改客户端的application.properties,添加另外两台注册中心的地址后,测试也可以访问到服务,停掉其中一台注册中心,发现依然可以使用client提供的服务,这样就实现了eureka注册中心的HA高可用。

d.eureka注册信息的结构和相关机制

eureka注册信息的结构为一个双层map,上面注册中心的UI界面展示了部分map的内容,它由如下几部分组成。

(1)第一层key为服务名,即上面的eureka-server或者service-hi,这是在application.properties文件中通过spring.application.name定义的。第一层value为一个map,记录注册的实例信息。

(2)第二层key为固定结构,即上面的youngchaolinmac:eureka-server:8090等,由系统用户名:服务名:端口号组成,第二层value为注册的实例对象,包含它的详细信息,如ip地址、端口、注册和续约的事件戳等信息。

相关的机制,有注册、续约、服务剔除和保护机制等。

(1)注册:服务提供者,如上面的client,启动服务后会根据注册中心的地址,携带自己的信息,通过http协议访问注册中心,注册中心接收到服务提供者的信息后保存在注册中心。

(2)续约:服务提供者每隔30s,会给注册中心发送一个‘‘心跳‘‘,告知自己的实例对象是存活的,否则注册中心会剔除死亡或不活跃的服务节点。

(3)剔除:注册中心每隔60s,会检查一次实例对象中的续约时间戳(保存在双层map中的第二层,在value中),如果超过90s没有续约,会将当前实例对象从第二层map中剔除,这样UI的Status下就会少一个实例对象。

(4)保护:集群的服务是很多的,会出现某个服务尽管续约了,但是由于网络或者通信的问题导致续约判断的失误从注册中心被剔除掉,如果大面积的出现这种情况会导致集群服务的瘫痪。为了避免这种情况的发生,springcloud提供了保护机制,即如果同一时间如果因为超时剔除的服务超过整体服务的15%以上,会被认为是非正常剔除,这样剔除不会实现,会保持集群服务原有的的状态。这种保护机制默认是开启的,也可以在application.properties中设置为关闭,即将eureka.server.enable-self-presevation=false来关闭。

ribbon

ribbon组件可以实现服务调服务, 需要引入RestTemplate来支持,它是一个客户端组件,会抓取在注册中心注册的服务信息,将其整理并保存,然后访问后端服务(上文的client)时会进行拦截,通过从spring容器中获取的负载均衡规则IRule对象,来实现对后端服务的访问逻辑。

为了实现ribbon的功能,需要提前准备2个client,上面已经准备了一个client,再需准备一个。另外还需要准备一个配置了ribbon的组件。

(1)准备一个新的client,当前工程下增添一个Module,修改端口号即可,其他无需修改,这里修改成了9089。

# 客户端端口
server.port=9089

# 客户端通过ip底层注册
# eureka.client.prefer-ip-address=true
eureka.client.preferIpAddress=true

# eureka-client的注册,和发现功能需设置为true,默认为true,也可以不用设置
eureka.client.regist-with-eureka=true
# 发现抓取注册信息的内容
eureka.client.fetch-registry=true

# 定义服务名称
spring.application.name=service-hi

# 注册中心的地址
eureka.client.serviceUrl.defaultZone=http://localhost:8088/eureka,http://localhost:8089/eureka,http://localhost:8090/eureka

(2)准备一个具有ribbon的服务组件,新建一个Module,注意pom文件需要添加ribbon的依赖,其他跟client的配置类似,另外ribbon服务组件的端口在application.properties文件中修改为8105,其他参考client的设置。

    <!--引入ribbon依赖-->
    <dependency>
      <groupId>org.springframework.cloud</groupId>
      <artifactId>spring-cloud-starter-ribbon</artifactId>
    </dependency>

(3)ribbon服务组件,添加启动类,启动类中使用@Bean返回一个RestTemplate对象,交给spring来管理,因为启动类注解@SpringBootApplication底层有@SpringBootConfiguration,这个配置类的下面又是@Configuration,因此启动类也可以作为配置类来使用,在其中配置一个bean。

package com;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.context.annotation.Bean;
import org.springframework.web.client.RestTemplate;

/**
 * 具有ribbon组件的服务启动类
 */
@SpringBootApplication
@EnableEurekaClient
public class StarterEurekaRibbon {
    public static void main(String[] args) {
        SpringApplication.run(StarterEurekaRibbon.class,args);
    }

    //使用restTemplate实现ribbon对客户端的拦截逻辑
    @Bean("restTemplate")
    @LoadBalanced //不加会访问不到其他微服务,提示找不到服务名,尽管有这个服务名的服务在运行着
    public RestTemplate getRestTemplate(){
        return new RestTemplate();
    }

}

(4)ribbon服务组件添加controller层和service层,在service层实现对请求的拦截,service层方法访问的是一个服务名,而不是具体的请求地址。因为这个服务能获取到注册中心其他服务的信息,将client对应的注册信息抓取过来,通过service-hi,就能获取到对应的双层map的第二层map的value,通过value里保存的ip、端口等信息,实现对真实服务的访问。

controller层

package com.boe.Controller;

import com.boe.Service.RibbonService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class RibbonController {

    @Autowired
    RibbonService ribbonService=null;

    //访问ribbon服务的地址
    @RequestMapping("helloribbon")
    public String test(String name){
        return "Ribbon work, "+ribbonService.hello(name);
    }
}

service层

package com.boe.Service;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

@Service
public class RibbonService {

    @Autowired
    RestTemplate restTemplate=null;

    //需要调用RestTemplate,通过服务名来实现对服务的访问,默认轮询
    public String hello(String name) {
        return restTemplate.getForObject("http://service-hi/hello?name="+name,String.class);
    }
}

(5)最后启动新添的client服务和有ribbon组件的服务,启动后正常均在注册中心注册。

(6)通过有ribbon组件的服务来访问client的服务,实现服务调服务,默认情况下是轮询的方式,当我多次访问如下地址后,会轮流出现9088和9089,说明访问的服务是轮流来的,也可以根据需求修改成其他的策略,需要在启动类中再添加如下代码。

    //自定义负载均衡-随机,还有其他的选择
    //需要配置bean,交给spring管理,如果ribbon组件在启动时会检测这个bean是否存在
    //如果不存在,就默认轮询
    @Bean
    public IRule initRandom(){
        return new RandomRule();//返回随机
        //return new RoundRobinRule();//返回负载轮询方式
        //return WeightedResponseTimeRule();//根据响应时间,返回对应大小权重值的方式,响应快权重值高,响应慢则权重值低
    }

访问有ribbon组件的服务,通过访问localhost:8105/helloribbon?name=messi,内部调用服务实际访问localhost:9089/hello?name=messi,实现了访问地址和真实服务地址的分离,向用户隐藏了真实的访问地址,这样显然更加的安全。

zuul

前面的ribbon可以实现服务调用服务, 其实springcloud已经提供了一个服务组件来完成上述的功能,那就是zuul网关,它底层就是基于ribbon和RestTemplate来实现,外界是不能直接访问后端提供的服务,需要通过zuul网关暴露的接口来实现访问,通过zuul的路由规则,通过访问的地址匹配到真实的地址后,再实现内部转发从而实现访问。

zuul网关一般配置在nginx,首先先通过nginx先过滤了一次地址,通过proxy_pass先转发到网关,网关再过滤一次,最后达到真的访问地址,如下图所示,下面按照下图的地址来实际配置一下。

(1)新增一个zuul服务,在IDEA中添加一个Module,pom文件参考前面的client,在此基础上增加zuul的依赖。

    <!--引入zull依赖-->
    <dependency>
      <groupId>org.springframework.cloud</groupId>
      <artifactId>spring-cloud-starter-zuul</artifactId>
    </dependency>

(2)配置application.properties文件,需添加zuul网关服务端口8108,并配置zuul.routes.test.path=/zuul-hi/**,以及zuul.routes.test.service-id=service-hi,这俩个配置是根据上图的地址来的,后续再分析。

# 网关端口
server.port=8108

# 客户端通过ip底层注册
# eureka.client.prefer-ip-address=true
eureka.client.preferIpAddress=true

# eureka-client的注册,和发现功能需设置为true,默认为true,也可以不用设置
eureka.client.regist-with-eureka=true
# 发现抓取注册信息的内容
eureka.client.fetch-registry=true
# 定义服务名称
spring.application.name=service-zull

# 注册中心的地址,两个server都需要配,用逗号隔开
eureka.client.serviceUrl.defaultZone=http://localhost:8088/eureka,http://localhost:8089/eureka,http://localhost:8090/eureka

# 配置zull网关

# 配置网关地址,**代表可以匹配多级目录
# 提供路由服务,通过不同的地址可以访问不同的服务

# 网关只会暴露使用的地址,具体的真实地址是隐藏的,因此网关如果宕机,外界将不能访问资源
# 因此网关可以通过nginx配置负载均衡

# zuul.routes.test.path里的test是路由名称

zuul.routes.test.path=/zuul-hi/**
# 匹配application name
zuul.routes.test.service-id=service-hi

(3)添加zuul网关启动类,注意需要添加@EnableZuulProxy的注解。

package com;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.cloud.netflix.zuul.EnableZuulProxy;

import javax.swing.*;

/**
 * zuul网关服务启动类
 */
@SpringBootApplication
@EnableEurekaClient
@EnableZuulProxy
public class StarterEurekaZull {
    public static void main(String[] args) {
        SpringApplication.run(StarterEurekaZull.class,args);
        System.out.println("zuul网关启动");
    }
}

(4)查看是否在注册中心注册zull服务,ok。

(5)配置nginx,实现第一层过滤,让外界访问的地址转发到网关地址,在nginx.conf目录下添加如下内容,并使用nginx -t查看是否配置正确,ok后使用nginx -s reload加载配置文件。

    # zuul网关测试新增server
    server {
        listen 8080;        # 需修改/etc/hosts文件,添加对www.test.com的本地解析
        server_name www.test.com;

        location /hellokitty {
            proxy_pass http://127.0.0.1:8108/zuul-hi/hello/;
        }

    }

(6)测试通过www.test.com:8080/hellokitty?name=messi来访问,发现可以访问到前面类似ribbon的访问效果。

为啥通过如上配置就可以访问到了真实的地址,下面简单分析下。

a.首先访问www.test.com:8080/hellokitty?name=messi,会被nginx拦截,由于匹配到hellokitty,会转发到新的地址http://127.0.0.1/zuul-hi/hello?name=messi

b.zuul网关服务接受到http://127.0.0.1/zuul-hi/hello?name=messi地址后,匹配到zuul.routes.test.path=/zuul-hi/**里的zuul-hi(**代表多级任意字符串),会截取变成hello?name=messi

c.然后根据zuul.routes.test.service-id=service-hi,将访问地址变成http://service-hi/hello?name=messi,而service-hi就是服务名,真实地址最后匹配后变成http://localhost:9088/hello?name=messi或者http://localhost:9089/hello?name=messi。

这样就实现了对真实地址的访问了,通过zuul配置在nginx,实现对外访问地址和真实地址分开,zuul是唯一的访问服务的入口,单台挂掉就会出现后端无法访问的可能,因此其需要在nginx配置集群,上面只配置了一个zuul服务,可以多开启几个zuul服务,然后在nginx通过upstream来转发到多个zuul服务,就可以实现zuul网关的集群,这里不展示了。

以上就是springcloud入门的整理,后续继续补充。

参考博文

(1)https://www.cnblogs.com/zhuwenjoyce/p/10261079.html springboot和springcloud版本对照

(2)https://segmentfault.com/a/1190000019294598 mac下nginx使用

原文地址:https://www.cnblogs.com/youngchaolin/p/11965306.html

时间: 2024-11-05 21:48:25

Springcloud使用入门的相关文章

微服务SpringCloud+Docker入门到高级实战

第一章 课程介绍和学习路线 1.微服务架构SpringCloud课程介绍简介:课程介绍和课程大纲讲解,讲课风格和重点内容理解技巧2.技术选型和学后水平简介:课程所需基础和技术选型讲解,学完课程可以到达怎样的程度, 第二章 架构演进和分布式系统基础知识 1.传统架构演进到分布式架构简介:讲解单机应用和分布式应用架构演进基础知识 (画图)2.微服务核心基础讲解简介:讲解微服务核心知识 :网关.服务发现注册.配置中心.链路追踪.负载均衡器.熔断3.常见的微服务框架简介:讲解常用的微服务框架4.微服务下

SpringCloud从入门到进阶(四)——使用SpringBoot搭建微服务

内容 SpringBoot整合SpringCloud的Eureka.Zuul等组件,快速实现简单易懂且具有服务熔断.负载均衡的分布式架构1.0,体验微服务的魅力. 版本 IDE:IDEA 2017.2.2 x64 JDK:1.8.0_171 manve:3.3.3 SpringBoot:1.5.9.RELEASE SpringCloud:Dalston.SR1 适合人群 ?Java开发人员 说明 转载请说明出处:SpringCloud从入门到进阶(四)--使用SpringBoot搭建微服务 参考

SpringCloud从入门到进阶(三)——路由接入Zuul

内容 SpringBoot整合SpringCloud的Eureka.Zuul等组件,快速实现简单易懂且具有服务熔断.负载均衡的分布式架构1.0,体验微服务的魅力. 版本 IDE:IDEA 2017.2.2 x64 JDK:1.8.0_171 manve:3.3.3 SpringBoot:1.5.9.RELEASE SpringCloud:Dalston.SR1 适合人群 ?Java开发人员 说明 转载请说明出处:SpringCloud从入门到进阶(三)--路由接入Zuul 参考 Linux入门实

SpringCloud从入门到进阶(四)——生产环境下Eureka的完全分布式部署

内容 由于前两节的内容我们知道,开启了preferIpAddress后,Eureka的伪分布式部署会提示replica不可用.这一节我们讲解如何在生产环境下部署完全分布式的Eureka集群,确保开启了preferIpAddress后replica的可用性. 版本 IDE:IDEA 2017.2.2 x64 JDK:1.8.0_171 manve:3.3.3 SpringBoot:1.5.9.RELEASE SpringCloud:Dalston.SR1 适合人群 Java开发人员 节点信息: 节

物联网架构成长之路(16)-SpringCloud从入门到吹水

1.前言 Spring Cloud 现在比较流行,版本更新也是蛮快的,网上资料也是很多.很多参考网上资料就可以学到了.这里给个 http://blog.csdn.net/forezp/article/details/70148833 2.放弃 本来还想写一篇Spring Cloud 入门环境搭建的博客, 后来想了想,还是算了,网上资料一大堆.这里就不写了. 3.吹水 下面就简单聊聊天,吹吹水算了 2018.01.18 笔记 公司网速不行,在进行Maven项目以来更新,偷偷写一些经历. 现在开始学

简谈SpringCloud的入门配置(二)

入门实例的四步骤: 1)配置Eureka服务器 在Spring官网上新建一个SpringCloud项目 增加Eurake组件 将其中的pom.xml文件拷贝至eclipse新建的Maven文件中 由于SpringCloud是基于SpringBoot的,先创建一个启动类Application package cn.lch; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoc

【SpringCloud】SpringCloud 快速入门(一)

SpringCloud简介 Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智能路由,微代理,控制总线).分布式系统的协调导致了样板模式, 使用Spring Cloud开发人员可以快速地支持实现这些模式的服务和应用程序.他们将在任何分布式环境中运行良好,包括开发人员自己的笔记本电脑,裸机数据中心,以及Cloud Foundry等托管平台. 特点 Spring Cloud专注于为典型的用例和可扩展性机制(包括其他用例)提供良好的开箱即

springcloud基础入门

1.环境搭建 在开始SpringCloud之前,先看一下一个简单的服务提供者和服务消费者.服务提供者提供一个REST风格的HTTP接口给服务消费者. 1.2pom配置 实体类 package com.test.springcloud.provider.pojo; public class User { private Long id; private String username; //getter/setter略 } controller层 package com.test.springcl

微服务SpringCloud+Docker入门到高级实战(教程详情)

第一章 课程介绍和学习路线 1.微服务架构SpringCloud课程介绍 简介:课程介绍和课程大纲讲解,讲课风格和重点内容理解技巧 2.技术选型和学后水平 简介:课程所需基础和技术选型讲解,学完课程可以到达怎样的程度, 1.IDEA JDK8 Maven SpringBoot基础 Linux 2.理解掌握并开发SpringCloud里面主流架构和组件的基础使用,还有部分源码原理的理解 3.掌握学习的技巧和解决问题的思路 第二章 架构演进和分布式系统基础知识 1.传统架构演进到分布式架构 简介:讲