SpringCloud-Eureka注冊與發現


這兩年可以說微服務是熱詞,也是新領域,學習的成本也較高,基礎東西太多比如什么Dubbo,zookeeper,Springboot等等。Dubbo也是實現服務治理又是阿里出的一套開源RPC框架,但是SpringCloud出現后便立即熱火朝天,當然阿里也加入了SpringCloud的孵化。

什么是微服務,分布式?

分布式:不同的模塊部署在不同的服務器上,可以更好的解決網站高並發。

微服務:架構設計概念,各服務間隔離(分布式也是隔離),自治(分布式依賴整體組合)其它特性(單一職責,邊界,異步通信,獨立部署)是分布式概念的跟嚴格執行 SOA到微服務架構的演進過程。簡單的說把項目拆分成各各模塊,用注冊中心的方式把服務都鏈接在一起

服務提供者與消費關系

  服務提供者:提供服務被人調用

  消費者:調用服務

今天我們說下SpringCloud的Eureka注冊中心

官方:

  Eureka是Netflix開發的服務發現框架,本身是一個基於REST的服務,主要用於定位運行在AWS域中的中間層服務,以達到負載均衡和中間層服務故障轉移的目的。SpringCloud將它集成在其子項目spring-cloud-netflix中,以實現SpringCloud的服務發現功能。
 
  Eureka包含兩個組件:Eureka Server和Eureka Client。
  Eureka Server提供服務注冊服務,各個節點啟動后,會在Eureka Server中進行注冊,這樣EurekaServer中的服務注冊表中將會存儲所有可用服務節點的信息,服務節點的信息可以在界面中直觀的看到。
  Eureka Client是一個java客戶端,用於簡化與Eureka Server的交互,客戶端同時也就是一個內置的、使用輪詢(round-robin)負載算法的負載均衡器。
  在應用啟動后,將會向Eureka Server發送心跳,默認周期為30秒,如果Eureka Server在多個心跳周期內沒有接收到某個節點的心跳,Eureka Server將會從服務注冊表中把這個服務節點移除(默認90秒)。
Eureka Server之間通過復制的方式完成數據的同步,Eureka還提供了客戶端緩存機制,即使所有的Eureka Server都掛掉,客戶端依然可以利用緩存中的信息消費其他服務的API。綜上,Eureka通過心跳檢查、客戶端緩存等機制,確保了系統的高可用性、靈活性和可伸縮性。
   環境搭建:
本次環境用Gradle+IDEA
1.先搭建注冊中心
2.主項目Gradle
group 'com.wang'
version '1.0-SNAPSHOT'

apply plugin: 'java'

sourceCompatibility = 1.8

buildscript {
    ext {//定義一個變量,統一規定springboot的版本
        springBootVersion = '1.5.10.RELEASE'
    }
    repositories {
        maven { url 'http://maven.aliyun.com/nexus/content/groups/public/' }
        jcenter()
        mavenCentral()
        //Spring repo
        maven { url "http://repo.spring.io/snapshot" }
        maven { url "http://repo.spring.io/milestone" }
        maven { url "http://repo.spring.io/release" }
        maven { url 'http://repo.spring.io/plugins-snapshot' }
    }

    dependencies {//用來打包
        classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
    }
}
//設定當前所有的項目的配置
allprojects {
    group 'com.ssx'
    version '1.0-SNAPSHOT'

    ext {
        springCloudVersion = 'Edgware.SR2'
    }

    repositories {
        maven { url 'http://maven.aliyun.com/nexus/content/groups/public/' }
        jcenter()
        mavenCentral()
        //Spring repo
        maven { url "http://repo.spring.io/snapshot" }
        maven { url "http://repo.spring.io/milestone" }
        maven { url "http://repo.spring.io/release" }
        maven { url 'http://repo.spring.io/plugins-snapshot' }
    }
}
//設定當前模塊項目中的配置
subprojects {
    apply plugin: 'java'
    apply plugin: 'idea'
    apply plugin: 'spring-boot'

    dependencies {
        //使用springboot-web組件,但是排除tomcat組件
        compile ('org.springframework.boot:spring-boot-starter-web'){
            exclude module:"spring-boot-starter-tomcat"
        }
        //使用undertow作為應用服務,作為servlet容器
        compile 'org.springframework.boot:spring-boot-starter-undertow'
        //使用健康檢查組件
        compile 'org.springframework.boot:spring-boot-starter-actuator'
        testCompile(
                group: 'junit', name: 'junit', version: '4.12'
        )
    }

    dependencyManagement {
        imports {
            //加上此配置后,如果需要引用springcloud的組件,就不需要再提供版本信息
            mavenBom "org.springframework.cloud:spring-cloud-dependencies:${springCloudVersion}"
        }
    }
}

3.注冊中心啟動類

package org.gw.reigster.conter;

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

/**
 * @DATA 2019-02-27 19:56
 * @Author 張國偉  WeChat:17630376104
 * @Description TODO
 */

@EnableEurekaServer #這個是表示這個項目作為euraka注冊中心
@SpringBootApplication
public class ReigsterConterProvider {
    public static void main(String[] args) {
        SpringApplication.run(ReigsterConterProvider.class,args);
    }
}

4.注冊中心yml

server:
  port: 8888
spring:
  application:
    name: reigster-conter
eureka:
  client:
    register-with-eureka: false #啟動時不注冊 本來就是注冊中心 表示自己是注冊中心
    fetch-registry: false  #不向注冊中心拉取數據
  server:
    enable-self-preservation: false #關閉自我保護 測試環境用 生產環境一般不用

5.啟動注冊中心訪問8888

這個為Eureka的信息頁面 可以看到這個時候 Instances currently registered with Eureka里面是No instances available 也就是這個時候還沒有服務注冊進來,下面我們寫注冊方

這個模塊為solr

package org.gw.solr;

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

/**
 * @DATA 2019-02-27 20:38
 * @Author 張國偉  WeChat:17630376104
 * @Description TODO
 */

@EnableEurekaClient   #這里為Eureka客戶端也就是服務
@SpringBootApplication
public class ProjectSolrProvider {
    public static void main(String[] args) {
        SpringApplication.run(ProjectSolrProvider.class, args);
    }
}

yml

server:
  port: 10002
spring:
  application:
    name: project-solr
eureka:
  client:
    service-url:
      defaultZone: http://localhost:8888/eureka/
  instance:
    prefer-ip-address: true

這時候我們啟動這個服務

這個時候可以看到 有個服務已經注冊進來

這個就是實現了 注冊也發現,那我們緊接這 如何實現服務與服務之間調用呢?我現在想project-shopping-mall模塊的controller調用solr的controller如何實現呢

package org.gw.shopping.mall;

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;

/**
 * @DATA 2019-02-27 20:24
 * @Author 張國偉  WeChat:17630376104
 * @Description TODO
 */
@EnableEurekaClient
@SpringBootApplication
public class ShoppingMallProvider {
    @LoadBalanced
    @Bean
    public RestTemplate resultTemplate() {
        RestTemplate template = new RestTemplate();
        return template;
    }


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

RestTemplate表示網絡請求 在啟動類里把他實例

package org.gw.shopping.mall.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

/**
 * @DATA 2019-02-27 20:45
 * @Author 張國偉  WeChat:17630376104
 * @Description TODO
 */
@Controller
public class ShopController {
    @Autowired
    private RestTemplate restTemplate;

    @RequestMapping("/toIndex")
    public String toIndex(Model model) {
        String msg = restTemplate.getForEntity("http://PROJECT-SOLR/solrSearc", String.class).getBody();
        model.addAttribute("msg", msg);
        return "index";
    }
}

這個為調用solr的controller根據名字調用

package org.gw.solr.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * @DATA 2019-02-27 20:40
 * @Author 張國偉  WeChat:17630376104
 * @Description TODO
 */
@RestController
public class SolrSearchController {

    @RequestMapping("/solrSearc")
    public String solrSearc(){
        return "從solr查詢到數據";
    }
}

意思就是說 我在shop里調用solr的controller他會返回一個從solr查詢到數據

我們來嘗試下

shop模塊里有thymeleaf模板展示數據

<!DOCTYPE html>
<html lang="en" xmlxs:th="http://www.thymeleaf.org" xmlns:xmlxs="http://www.w3.org/1999/xhtml"
      xmlns:th="http://www.w3.org/1999/xhtml">
<head>
    <meta charset="UTF-8"/>
    <title>Title</title>
</head >
<body>
<h1>歡迎進入商城</h1>
<h2>從solr微服務中查到的數據::::<span th:text="${msg}"></span></h2>
</body>
</html>

可以看到 已經成功拿到數據

 

到這里,我們已經實現服務的注冊與發現,下章說 鏈路跟蹤,有問題請及時評論。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM