Spring Cloud 微服务简介

1. 单体应用优化

    1.1 可使用SOA面向服务架构(将每个模块分开,某个模块出问题了,不会影响其他模块)
    1.2 如果某个服务于其他服务有调用关系,那么就需用到ESB(企业服务总线)

2. 微服务架构

    2.1 将单体应用切分为小服务单元

3. Spring Cloud

    3.1 是一个工具箱

    3.2 基于SpringBoot,封装了Netflix的框架

    3.3 将Netflix与Spring容器进行整合

4. Spring Cloud整合的Netflix框架

    4.1 Eureka:基于REST服务的分布式中间件,主要用于服务管理

    4.2 Hystrix:容错框架,通过添加延迟阀值以及容错的逻辑,来帮助我们控制分布式系统间组件的交互。

    4.3 Feign:一个REST客户端,目的是为了简化WebService客户端的开发

    4.4 Ribbon:负载均衡框架    Zuul:为微服务集群提供过代理,过滤,路由等功能

5. 微服务的优点

    5.1 易于开发和维护:由于微服务单个模块就相当于一个项目,开发这个模块我们就只需关心这个模块的逻辑即可,代码量和逻辑复杂度都会降低,从而易于开发和维护。

    5.2 启动较快:这是相对单个微服务来讲的,相比于启动单体架构的整个项目,启动某个模块的服务速度明显是要快很多的。

    5.3 局部修改容易部署:在开发中发现了一个问题,如果是单体架构的话,我们就需要重新发布并启动整个项目,非常耗时间,但是微服务则不同,哪个模块出现了bug我们只需要解决那个模块的bug就可以了,解决完bug之后,我们只需要重启这个模块的服务即可,部署相对简单,不必重启整个项目从而大大节约时间。

   5.4 技术栈不受限:比如订单微服务和电影微服务原来都是用java写的,现在我们想把电影微服务改成nodeJs技术,这是完全可以的,而且由于所关注的只是电影的逻辑而已,因此技术更换的成本也就会少很多。

 

小白必看,大神略过,下面这段介绍 会帮助你更快的理解 SpringCloud 微服务

在搭建 SpringCloud 微服务之前呢,先大概的说一下微服务结构,SpringCloud 微服务是由三个部分组成:

    1. 服务器:将服务器当作是平时查电话的114平台

    2. 服务提供者:将服务提供者当作是警察局,将警察局的电话放到了114平台上面

    3. 服务调用者:服务调用者肯定是我们啦,我们就可以通过114平台查到警察局的电话了

 

上面简单的介绍了一下什么Spring Cloud微服务,那么下面直接上代码,为的就是能让初学者快速上手,自己搭建起Spring Cloud微服务框架。

 

搭建 Eureka 服务器(114平台)

什么是Eureka:Eureka是Netflix开发的服务发现组件,本身是一个基于REST的服务。Spring Cloud将它集成在其子项目spring-cloud-netflix中,以实现Spring Cloud的服务发现功能。

Eureka的配置可以说是非常简单的,配置如下:

 

pom.xml

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.0.1.RELEASE</version>
</parent>

<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-dependencies</artifactId>
            <version>Finchley.SR1</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>

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

application.yml

server:
  port: 8761
eureka:
  client:
    register-with-eureka: false  不将自己注册到服务器,因为自己本身就是服务器
    fetchRegistry: false  不抓取服务列表

Application.java

@SpringBootApplication
@EnableEurekaServer
public class Application {

    public static void main(String[] args) {
        new SpringApplicationBuilder(Application.class).web(true).run(args);
    }
}

启动后,如果能够正常访问到这个页面的朋友们,恭喜你们  成功了 !!!

想要做集群的话,也是很简单的,只需在服务端改一下配置就可以了,废话不多说,请继续往下看:

需要修改系统文件:C:/Windows/System32/drivers/etc/hosts

增加映射:127.0.0.1 slave1 slave2(无论是slave1还是slave2,都会映射到127.0.0.1)(这个映射一定要加,否则映射时会出问题)

因加入了集群,那么就需要对每个服务进行单独启动(这里进行手动启动服务)区别如下:

 

Application.java

@SpringBootApplication
@EnableEurekaServer
public class Application {

    public static void main(String[] args) {
        Scanner scan = new Scanner(System.in);// 需手动输入:刚刚配置过映射的 slave1、slave2
        String pro = scan.nextLine();
        new SpringApplicationBuilder(Application.class).profiles(pro).run(args);
    }
}

 

注:

在这里有一点需要注意的是:在application.yml配置中的书写的规范,换行后 需加两个空格(一定不可以使用Tab缩进,会报错的)

两个配置中间的横杠:---(这里的“-”,一定要是三个,多一个 少一个都不行)

name: spring-cloud-server(Eureka程序的项目名)

profiles: slave1(刚刚配置映射时的名称)

 

application.yml

server:
  port: 8761
spring:
  application:
    name: cluster-114
  profiles: slave1
eureka:
  instance:
    hostname: slave1
  client:
    serviceUrl:
      defaultZone: http://slave2:8762/eureka/
---
server:
  port: 8762
spring:
  application:
    name: cluster-114
  profiles: slave2
eureka:
  instance:
    hostname: slave2
  client:
    serviceUrl
      defaultZone: http://slave1:8761/eureka/

 

分别启动后的截图:http://localhost:8761/   http://localhost:8762/

 

 

到这里 Eureka 服务器的搭建已经结束了,那么下面说一下  如何搭建 服务提供者 也就是在上面提到的 “警察局”

 

搭建 Eureka 客户端_服务提供者(警察局)

pom.xml

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>1.5.13.RELEASE</version>
</parent>
<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-dependencies</artifactId>
            <version>Dalston.SR5</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>
<dependencies>
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-config</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-eureka</artifactId>  不用翻到上面去找不同啦~  区别就在这里,客户端是 eureka,而服务器端是 eureka-server
    </dependency>
</dependencies>

application.yml

server:
  port: 8080  为了避免端口被占用,这里自定义端口号
spring:
  application:
    name: first-police  最好起个有意义的,该name是要显示在服务列表中的
eureka:
  client:
    serviceUrl:
      defaultZone: http://localhost:8761/eureka/  这里需要将自己注册到服务器

为了测试,创建一个简单的Controller,以便调用

@RestController
public class MyController {
    
    @RequestMapping(value = "/call/{no}", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
    public String call(@PathVariable String no){
        return "自定义编号:"+no+"   成功获取警局电话号码!";
    }

}

PoliceApplication.java

@SpringBootApplication
@EnableEurekaClient
public class PoliceApplication {
    
    public static void main(String[] args) {
        new SpringApplicationBuilder(PoliceApplication.class).web(true).run(args);
    }
    
}

以上就是 服务提供者 的全部代码,启动后可在服务列表中看到该服务,见下图:

 

上面服务提供者的配置已经说完了,那么下面说一说 服务提供者应该如何向服务器注册服务(本次在Eureka服务器做了集群之后,加入服务提供者)

 

pom.xml:与上面的配置相同

application.yml:既然想要开启多个服务实例,那么就需要启动不同的端口来实现,将server.port配置删除,在启动时进行手动输入端口号来启动。。。

spring:
  application:
    name: cluster-police
eureka:
  client:
    serviceUrl:
      defaultZone: http://localhost:8761/eureka/, http://localhost:8762/eureka/  因为我们启动了两个eureka服务,所以要将自己同时注册到两个服务器上

MyController.java  在这里我们对之前的方法进行修改,为的就是让大家更直观的看出,负载均衡是否起了作用

@RestController
public class MyController {
    
    @RequestMapping(value = "/call/{no}", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
    public String call(@PathVariable String no, HttpServletRequest request){
        return "请求地址:"+request.getRequestURL()+"   自定义编号:"+no+"   成功获取警局电话号码!";// 在这里打印出请求地址
    }

}

PoliceApplication.java

@SpringBootApplication
@EnableEurekaClient
public class PoliceApplication {
    
    public static void main(String[] args) {
        Scanner scan = new Scanner(System.in);
        String port = scan.nextLine();
        new SpringApplicationBuilder(PoliceApplication.class).properties("server.port="+port).run(args);// 在启动时,手动输入端口号  在这里我们分别用8080、8081两个端口来启动下
    }
    
}

 

分别启动后的截图:http://localhost:8761/   http://localhost:8762/

 

搭建 Eureka 客户端_服务调用者(我们就是服务调用者)

pom.xml

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>1.5.13.RELEASE</version>
</parent>
<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-dependencies</artifactId>
            <version>Dalston.SR5</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>
<dependencies>
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-config</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-eureka</artifactId>  因为服务调用者也属于Eureka客户端,所以在这里引入eureka
    </dependency>
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-ribbon</artifactId>  引入ribbon负载均衡依赖,在后面会介绍到负载均衡,ribbon是使用在客户端的框架
    </dependency>
</dependencies>

application.yml 

server:
  port: 9091
spring:
  application:
    name: first-person
eureka:
  client:
    serviceUrl:
      defaultZone: http://localhost:8761/eureka/  服务调用者也是一样,需要将自己注册到服务器

创建一个Controller,在接口中去调用我们刚刚注册好的服务提供者(警察局)

@RestController
@Configuration
public class MyController {
    
    /**
     * RestTemplate 是由 Spring Web 模块提供的工具类,与 SpringCloud 无关,是独立存在的
     * 因 SpringCloud 对 RestTemplate 进行了一定的扩展,所以 RestTemplate 具备了负载均衡的功能
     * @return RestTemplate
     */
    @Bean
    @LoadBalanced
    public RestTemplate getRestTemplate(){
        return new RestTemplate();
    }
    
    @RequestMapping("/call/{no}")
    public String call(@PathVariable String no){
        RestTemplate rtl = getRestTemplate();
        return rtl.getForObject("http://first-police/call/"+no, String.class); // http://提供者服务实例名称/接口...
    }

}

PersonApplication.java 

@SpringBootApplication
@EnableEurekaClient
public class PersonApplication {
    
    public static void main(String[] args) {
        new SpringApplicationBuilder(PersonApplication.class).web(true).run(args);
    }
}

 

启动后访问,会发现服务列表中有两个服务:

服务调用者需调用服务提供者,所以访问:http://localhost:9091/call/1

 

前面给大家讲解了如何搭建“Eureka服务器”和“服务提供者”的集群。 想要知道上面配置的集群有没有起作用呢?那么接下来我们就要测试一下。。。

pom.xml:上面已经贴了配置,在这里就不再重复贴了

 

application.yml:

server:
  port: 9999  自定义端口
spring:
  application:
    name: cluster-person
eureka:
  client:
    serviceUrl:
      defaultZone: http://localhost:8761/eureka/  这里也需要向服务器注册服务

 

Controller在上面也有贴,call方法没有做任何改变,在这里就不再重复贴了

至于启动类,没有特殊化,和之前的启动方法相同

@SpringBootApplication
@EnableEurekaClient
public class PersonApplication {
    
    public static void main(String[] args) {
        new SpringApplicationBuilder(PersonApplication.class).web(true).run(args);
    }
}

接下来,启动 看效果  浏览器访问:http://localhost:9999/call/123

 

 

由此可见,交叉访问,我们所配置的负载均衡起作用了,负载均衡也可自定义,在本文中暂不讲述。

 

posted on 2018-09-14 11:16  沛昕的博客  阅读(700)  评论(0编辑  收藏  举报