SpringCloud - 学习笔记

一、SpringCloud简介

SpringCloud是一个基于SpringBoot实现的云应用开发工具,为开发人员提供了快速构建分布式系统的一些工具,包括配置管理、服务发现、断路器、路由、微代理、控制总线、全局锁、决策竞选、分布式会话等等。

二、服务注册与发现

Spring Cloud Eureka

Spring Cloud Eureka是Spring Cloud Netflix(Spring Cloud子项目之一)项目下的服务治理模块。主要是对Netfilix公司一系列的开源产品的包装。通过简单的配置,开发者就可以快速在应用中配置常用模块并构建庞大的分布式系统。主要提供的模块: 服务发现(Eureka)、断路器(Hystrix)、智能路由(Zuul)、客户端负载均衡(Ribbon)

  • 创建服务注册中心(euraka server)

首先创建一个基础的Spring Boot工程。build.gradle文件如下:

plugins {
    id 'org.springframework.boot' version '2.1.3.RELEASE'
    id 'java'
}

apply plugin: 'io.spring.dependency-management'

group = 'com.example'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '1.8'

repositories {
    mavenCentral()
}

ext {
    set('springCloudVersion', 'Greenwich.SR1')
}

dependencies {
    implementation 'org.springframework.cloud:spring-cloud-starter-netflix-eureka-server'
    testImplementation 'org.springframework.boot:spring-boot-starter-test'
//    implementation 'org.springframework.cloud:spring-cloud-starter-eureka'
}

dependencyManagement {
    imports {
        mavenBom "org.springframework.cloud:spring-cloud-dependencies:${springCloudVersion}"
    }
}

通过@EnableEurekaServer注解启动一个服务注册中心,提供给其他应用。

@SpringBootApplication
@EnableEurekaServer
public class EurekaServerApplication {

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

在默认情况下,该服务注册中心也会将自己作为客户端来尝试注册自己,所以我们要禁止他的客户端注册行为,需要配置application.yml文件:

spring:
  application:
    name: eureka-server

server:
  port: 8888

eureka:
  instance:
    hostname: localhost
  client: #设置下面属性为false表明自己是一个 eureka server
    register-with-eureka: false
    fetch-registry: false

访问localhost:8888显示内容如下:

Eureka

  • 创建服务提供者(eureka-client)

首先创建一个基础的Spring Boot工程。build.gradle文件如下:

plugins {
    id 'org.springframework.boot' version '2.1.3.RELEASE'
    id 'java'
}

apply plugin: 'io.spring.dependency-management'

group = 'com.example'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '1.8'

repositories {
    mavenCentral()
}

ext {
    set('springCloudVersion', 'Greenwich.SR1')
}

dependencies {
    implementation 'org.springframework.cloud:spring-cloud-starter-netflix-eureka-client'
    testImplementation 'org.springframework.boot:spring-boot-starter-test'
}

dependencyManagement {
    imports {
        mavenBom "org.springframework.cloud:spring-cloud-dependencies:${springCloudVersion}"
    }
}

创建/client请求处理接口,通过DiscoverClient对象,打印出服务实例信息。


@RestController
public class DiscoveryClientController {
    @Autowired
    DiscoveryClient discoveryClient;

    @GetMapping("/client")
    public String discoveryClient(){
        String services = "Services: " + discoveryClient.getServices();
        System.out.println(services);
        return services;
    }
}

通过@EnableDiscoveryClient注解,激活Eureka中的DiscoveryClient实现。

@SpringBootApplication
@EnableEurekaClient
public class EurekaClientApplication {

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

application.yml文件中注明自己的服务注册中心的地址

spring:
  application:
    name: eureka-client
    
server:
  port: 8000
  
eureka:
  client:
    service-url:
      defaultZone: http://localhost:8888/eureka/

注:
spring.application.name属性,指定微服务的名称,后面直接调用该名称就可以进行服务访问。
eureka.client.service-url.defaultZone对应服务注册中心的配置内容,指定服务注册中心的位置。

启动成功后再次访问localhost:8888结果如下

eureka

当我们访问eureka-client中的localhost:8000/client可以获取当前服务清单:

注:
输出的信息eureka-client是通过Spring Cloud定义的DiscoveryClient接口在eureka的实现中获取到的所有清单列表。

三、服务消费者

在Spring Cloud Commons中提供大量的与服务治理相关的抽象接口,包括DidcoveryClient。这里我们介绍LoadBalancerClient负载均衡客户端的抽象定义。
创建一个服务消费工程eureka-consumer

plugins {
    id 'org.springframework.boot' version '2.1.3.RELEASE'
    id 'java'
}

apply plugin: 'io.spring.dependency-management'

group = 'com.example'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '1.8'

repositories {
    mavenCentral()
}

ext {
    set('springCloudVersion', 'Greenwich.SR1')
}

dependencies {
    implementation 'org.springframework.boot:spring-boot-starter-web'
    implementation 'org.springframework.boot:spring-boot-starter-actuator'
    testImplementation 'org.springframework.boot:spring-boot-starter-test'
    compile group: 'org.springframework.cloud', name: 'spring-cloud-starter-eureka', version: '1.4.6.RELEASE'

}

dependencyManagement {
    imports {
        mavenBom "org.springframework.cloud:spring-cloud-dependencies:${springCloudVersion}"
    }
}

配置application.yml文件,指定eureka注册中心地址

spring:
  application:
    name: eureka-consumer

server:
  port: 8100

eureka:
  client:
    service-url:
      defaultZone: http://localhost:8888/eureka/

创建应用主类。初始化RestTemplate,用来真正发起REST其请求。@EnableDiscoveryClient注解用来将当前应用加入到服务治理体系中。

package com.example.eurekaconsumer;

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

@SpringBootApplication
@EnableDiscoveryClient
public class EurekaConsumerApplication {
    @Bean
    public RestTemplate restTemplate(){
        return new RestTemplate();
    }

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

创建一个接口用来消费eureka-client提供的接口

package com.example.eurekaconsumer.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.loadbalancer.LoadBalancerClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

@RestController
public class ConsumerController {
        @Autowired
        LoadBalancerClient loadBalancerClient;
        @Autowired
        RestTemplate restTemplate;

        @GetMapping("/consumer")
        public String dc() {
            ServiceInstance serviceInstance = loadBalancerClient.choose("eureka-client");
            String url = "http://" + serviceInstance.getHost() + ":" + serviceInstance.getPort() + "/client";
            System.out.println(url);
            return restTemplate.getForObject(url, String.class);
        }
}

注:

  • 注入LoadBalancerClientRestTemplate,并在接口中实现。通过LoadBalancerClient的choose函数来负载均衡选出一个eureka-client的服务实例。
  • 服务实例的基本信息存储在ServiceInstance中。
    最后利用RestTemplate来调用服务提供者的接口。

通过访问http://localhost:8100/consumer

image.png

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 219,869评论 6 508
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,716评论 3 396
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 166,223评论 0 357
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 59,047评论 1 295
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 68,089评论 6 395
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,839评论 1 308
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,516评论 3 420
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,410评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,920评论 1 319
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 38,052评论 3 340
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,179评论 1 352
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,868评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,522评论 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,070评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,186评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,487评论 3 375
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,162评论 2 356

推荐阅读更多精彩内容