2、SpringCloud快速搭建

SpringCloud构建微服务是基于SpringBoot开发的。
创建服务提供者的访问方法,消费者如何访问提供者,SpringCloud是基于rest的访问,他们之间是通过json进行交互

创建服务提供者

依赖

<!--springboot开发web项目的依赖-->
<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>
        <exclusions>
            <exclusion>
                <groupId>org.junit.vintage</groupId>
                <artifactId>junit-vintage-engine</artifactId>
            </exclusion>
        </exclusions>
    </dependency>
</dependencies>

controller

@RestController
public class HelloController {
    @RequestMapping("/service/hello")
    public String hello(){
//        业务处理(省略)
        return "hello spring clound";
    }
}

创建服务消费者

创建一个新的springboot项目
开发消费者方法,去消费服务提供者提供的服务,这个消费者方法也是一个Controller

@RestController
public class WebController {

    @Autowired
    private RestTemplate restTemplate;

    @RequestMapping("/web/hello")
    public String hello(){
//        逻辑判断(省略)

//        调用SpringCloud服务提供者提供的服务(通过RestTemplate这个类远程调用服务)
        return restTemplate.getForEntity("http://localhost:8080/service/hello", String.class).getBody();
    }

配置RestTemplate类

//配置文件
@Configuration
public class BeanConfig {
    /**
     * @Bean 等价于 <bean id="restTemplate" class="xxx.xxx.RestTemplate"/>
     *
     * @return
     */
    @Bean
    public RestTemplate restTemplate(){
        return new RestTemplate();
    }
}

端口配置避免两个项目的端口号冲突

server.port=8081

访问
通过http://localhost:8081/web/hello访问消费者方法,消费者方法会调用服务提供者提供的方法

Spring Cloud结构的远程调用模式

服务提供者的服务需要注册到服务中心上,消费者通过注册中心获取提供者注册的服务,然后进行调用

走进服务注册中心Eureka

  微服务架构中,服务注册与发现是核心组件之一,手动指定每个服务是很低效的,SpringCloud提供多种服务注册与发现的实现方式,如:Eureka、Consul、Zookeeper。
  SpringCloud支持最后的是Eureka,然后Consul、Zookeeper

服务注册

  将服务所在主机、端口、版本号、通信协议等信息登记到注册中心上。

什么是服务发现?

  服务消费者向注册中心请求已经登记的服务列表,然后得到某个服务的主机、端口、版本号、通信协议等信息、从而实现对具体服务的调用。

Eureka

  • 一个服务治理组件,主要包括服务注册与发现,用来搭建服务注册中心
  • Eureka 是一个基于 REST 的服务,用来定位服务,进行中间层服务器的负载均衡和故障转移
  • Eureka 由 Netflix 提供,SpringCloud进行二次封装
  • C/S 设计架构:
    • Eureka Server(服务端)是服务中心;维护人员可以通过Eureka Server 来监控系统中的各个微服务是否正常运行
    • Eureka Client(客户端)是一个java客户端,用于简化与服务器的交互,负载均衡,服务的故障切换等;
    • 通过客户连接到服务端,并维持心跳连接;

Eureka 与 Zookeeper 的比较

CAP理论 一个分布式系统不可能同时满足cap (C:数据一致性,A:服务可用性,P:分区容错性)

  • 微服务本身就分为多个节点,当一个节点出现故障时,其他节点不会随之瘫痪,这就是容错性是分布式系统必须保证的;
  • 服务可用性 和 数据一致性 两者无法并存只能进行取舍,Zookeeper保证的是CP,而Eureka则是AP

Zookeeper

例如:一个Zookeeper集群,有三个节点,其中master因网络故障或与其他节点失去联系,那么Zookeeper就会在剩下的节点中选举出一个节点作为master,但是选举的过程需要时间,而这段时间整个Zookeeper集群是不可用的,也就是注册服务瘫痪,Provider无法向注册中心注册服务,这时就失去了C(服务可用性)。Zoo因网络问题导致Zookeeper失去master节点是大概率时间,虽然能回复,但是选举时间内导致服务注册长期不可用是难以容忍的。

Eureka

Eureka集群与Zookeeper不同,节点之间没有主从关系,如果某个节点挂了,剩余节点依然能提供注册和查询服务。如果Eureka Client 向 Eureka Server 注册时发现连接失败,会自动切换到其他正常的节点。但是无法保证查到的信息是最新的(不保证强一致性)

例如:
Eureka Client 向 Eureka Server 注册服务,注册完后,由于某些原因客户端停掉了该服务,这是的服务端有可能没有进行更新,导致消费者(consumer)去注册中心(Eureka Server)中获取该服务的注册信息是有的,但是调用服务的时候却无法调用的问题。

搭建并配置Eureka服务注册中心

Spring Cloud 中的Eureka 服务注册中心实际上也是一个Spring Boot工程,通过引入相关依赖和注解配置,让Spring Boot构建的微服务应用与Eureka进行整合整合。

步骤:
1.创建一个SpringBoot项目,并且添加SpringBoot的相关依赖;
(省略)
2.添加Eureka的依赖

    <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>
            <exclusions>
                <exclusion>
                    <groupId>org.junit.vintage</groupId>
                    <artifactId>junit-vintage-engine</artifactId>
                </exclusion>
            </exclusions>
        </dependency>

        <!-- 添加Eureka依赖-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
        </dependency>
    </dependencies>

    <dependencyManagement>
        <!--添加依赖管理-->
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>Edgware.SR1</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-dependencies</artifactId>
                <version>${spring-boot.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                    <encoding>UTF-8</encoding>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

    <!--还可以配置Repository-->
    <repositories>
        <repository>
            <id>spring-milestones</id>
            <name>Spring Milestone</name>
            <url>https://repo.spring.io/libs-milestone</url>
            <snapshots>
                <enabled>false</enabled>
            </snapshots>
        </repository>
    </repositories>

3.在Spring Boot 的入口类上添加一个@EnableEurekaServer注解,用于开启Eureka注册中心服务端

@SpringBootApplication
@EnableEurekaServer //开启Eureka注册中心服务端
public class Application {

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

4.在application.properties或yaml文件中配置Eureka服务注册中心信息

server.port=8761

#配置该服务注册中心的hostname(填ip)
eureka.instance.hostname=localhost
#由于我们目前创建的应用是一个服务注册中心,而不是普通的应用。
# 默认情况下,这个应用会向注册中心(也是它自己)注册它自己,设置为false表示禁止这种自己向自己注册的默认行为
eureka.client.register-with-eureka=false
#表示不去检索其他的服务,因为服务注册中心本身的职责就是维护服务实例,它不需要检索其他服务
eureka.client.fetch-registry=false
#指定服务注册中心的位置
eureka.client.service-url.defaultZone=http;//${eureka.instance.hostname}:${server.port}/eureka/

启动与测试Eureka服务注册中心

1.完成上面的项目搭建后,启动springboot程序,执行main方法;
2.启动成功之后,通过在浏览器地址栏访问我们的注册中心

访问界面如下:

注意

启动失败的话,肯能是SpringBoot与SpringCloud之间的兼容问题
可以通过SpringCloud官网进行访问点击跳转SpringCloud,点检Deference Doc,查看兼容版本

向Eureka服务注册中心注册服务

将服务提供者注册到Eureka注册中心

步骤
1.该服务提供者Provider添加Eureka的依赖
服务提供者想注册中心注册服务,需要连接eureka,所以需要eureka客户端的支持

<!-- 添加Eureka客户端依赖>
<dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
    </dependency>
</dependencies>

<dependencyManagement>
    <dependencies>
        <!-- 添加SpringCloud依赖管理-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-dependencies</artifactId>
            <version>Hoxton.RELEASE</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-dependencies</artifactId>
            <version>${spring-boot.version}</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>

2.激活Eureka中的EnableEurekaClient功能:
在SpringBoot的启动类上添加@EnableEurekaClient注解来表示自己是一个Eureka Client,使得服务可用连接Eureka注册中心;

3.配置服务名称和注册中心地址

#配置服务的名称,通常与项目名一致(通过名称访问微服务)
server.servlet.context-path: /01springcloud-service-provider
#eureka的访问地址
eureka.client.service-url.defaultZone=http://localhost:8761/eureka

4.启动服务提供者SpringBoot程序的main方法运行

5.访问Eureka服务中心
这是就有一个服务注册上了

从Eureka服务注册中心发现和消费服务

  • 服务的发现由Eureka客户端实现
  • 服务的消费由Ribbon实现
  • 服务的调用需要Eureka Client 和 Ribbon共同完成

Eureka Client
Eureka 客户端时一个java客户端,用来连接Eureka服务端,与服务端进行交互,负载均衡,服务的故障切换等

Ribbon

  • Ribbon是基于Http 和 TCP 的客户端负载均衡器。
  • 使用Ribbon对服务进行访问时,它会扩展Eureka客户端的服务发现功能,实现从Eureka注册中心中获取服务端列表,并通过Eureka客户端来确定服务端是否已经启动。
  • Ribbon在Eureka客户端服务发现的基础上,实现了对服务实例的选择策略,从而实现对服务的负载均衡消费。

服务消费者调用服务提供者

1.消费者项目添加Eureka Client的依赖
consumer从注册中心获取服务,需要连接Eureka,所以需要Eureka支持

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>

<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-dependencies</artifactId>
            <version>Hoxton.RELEASE</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-dependencies</artifactId>
            <version>${spring-boot.version}</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>

2.激活Eureka中的EnableEurekaClient功能
在启动类上添加@EnableEurekaClient注解

3.配置服务的名称和注册中心的地址

#配置服务的名称,通常与项目名一致(通过名称访问微服务)
server.servlet.context-path: /02springcloud-service-consumer
#eureka的访问地址
eureka.client.service-url.defaultZone=http://localhost:8761/eureka

4.调用服务提供者时使用ribbon来调用

//配置文件
@Configuration
public class BeanConfig {
    /**
     * @Bean 等价于 <bean id="restTemplate" class="xxx.xxx.RestTemplate"/>
     *
     * @return
     */
    @LoadBalanced //ribbon支持
    @Bean
    public RestTemplate restTemplate(){
        return new RestTemplate();
    }
}

加入ribbon的支持,那么调用的时候,使用服务名称来访问即可

@RestController
public class WebController {

    @Autowired
    private RestTemplate restTemplate;

    @RequestMapping("/web/hello")
    public String hello(){

//        Eureka + Ribbon的调用服务的方式(这种方式不再需要ip地址和端口号了)
        return restTemplate.getForEntity("http://01-SPRINGCLOUD-SERVICE-PROVIDER/service/hello", String.class).getBody();

    }
}

5.启动消费者程序

6.访问消费者
检验是否能正常调用

posted @ 2020-09-10 11:43  lawrence林  阅读(292)  评论(0编辑  收藏  举报