[java學習筆記] eureka注冊中心和微服務之間的調用


注冊中心

  由於微服務多為集群部署,在這種情況下,微服務之間要調用彼此的接口,如果使用url或者ip地址的形式調用會帶來很多麻煩,例如無法確定要連的主機是否可用。在這種情形下,便需要一個系統對所有的微服務進行統一的管理,實時的確定各個微服務所部署的主機的可用狀態,這個系統就是注冊中心。

  注冊中心主要的作用就是統一管理各個微服務,微服務向注冊中心注冊自己的信息,然后定時的和注冊中心通信,以便注冊中心區分可用和不可用的主機;而要調用服務的程序則向注冊中心申請相應服務,注冊中心返回給程序請求服務可用的主機ip以及端口號,這樣實現服務的調用,常用的注冊中心有eureka,zookeeper等,這里介紹了eureka的使用。

  eureka是springcloud下的一個注冊中心,通過它可以實現微服務的統一管理;

eureka的部署:

  首先父工程的pom文件:

<?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>
    <!--springboot依賴,微服務工程使用springboot構建-->
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.0.1.RELEASE</version>
    </parent>
    
    <groupId>cn.ly</groupId>
    <artifactId>ly_cloud_test</artifactId>
    <packaging>pom</packaging>
    <version>1.0-SNAPSHOT</version>
    <modules>
        <module>ly_eureka</module>
        <module>ly_feignribbon_test_server01</module>
        <module>ly_fergnribbon_test_server02</module>
    </modules>
    <properties>
        <okhttp.version>3.9.1</okhttp.version>
        <feign-okhttp.version>8.18.0</feign-okhttp.version>
    </properties>
    <!--依賴管理,對子工程進行相應的依賴版本管理-->
    <dependencyManagement>
        <dependencies>
            <!--springcloud依賴-->
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>Finchley.SR1</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            <!--遠程調用-->
            <dependency>
                <groupId>com.squareup.okhttp3</groupId>
                <artifactId>okhttp</artifactId>
                <version>${okhttp.version}</version>
            </dependency>
            <dependency>
                <groupId>com.squareup.okhttp3</groupId>
                <artifactId>okhttp</artifactId>
                <version>${okhttp.version}</version>
            </dependency>
            <dependency>
                <groupId>com.netflix.feign</groupId>
                <artifactId>feign-okhttp</artifactId>
                <version>${feign-okhttp.version}</version>
            </dependency>
            
        </dependencies>
    </dependencyManagement>


</project>

然后建立eureka子工程ly_eureka,

引入依賴:

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

配置文件application.yml:

server:
  port: ${PORT:50101} #端口號
spring:
  application:
    name: ly-govern-center #服務名
eureka:
  client:
    register-with-eureka: false #是否向注冊中心注冊服務
    fetch-registry: false #是否向注冊中心發現服務
    serviceUrl:
      defaultZone: http://localhost:50101/eureka/ #注冊中心地址,配置多服務器注冊中心時需要將多個ip用‘,’分隔
  server:
    enable-self-preservation: false #自我保護設置,當微服務不再報告狀態時,也不會立即將其刪除,在開發階段建議設置false
    eviction-interval-timer-in-ms: 60000 #服務注冊表清理間隔
  instance:
    hostname: ${EUREKA_DOMAIN:eureka01}

springboot的主函數:

package cn.ly;

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

@SpringBootApplication
@EnableEurekaServer // 聲明這是一個eureka的服務器
public class GovernCenterApplication {
    public static void main(String[] args) {
        SpringApplication.run(GovernCenterApplication.class, args);
    }
}

直接啟動即可完成eureka注冊中心的部署,啟動后,在瀏覽器中輸入:localhost:50101看到eureka頁面即表明部署成功;

作為一個服務,其本身也是可以集群部署的,只要在配置文件defaultzone中將所有的要部署的ip寫上去就行了,中間用逗號隔開;

向eureka中注冊服務

服務使用springboot來搭建,創建子工程server01,引入依賴:

<!--向eureka注冊服務依賴-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>

在主函數上添加注解:

@EnableDiscoveryClient //表明該工程是eureka的客戶端,會向eureka注冊服務並從中發現服務

提供一個簡單的controller:

package cn.ly.controller;

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

@Controller
public class HelloController {
    int i = 0;
    @ResponseBody
    @RequestMapping("/hello")
    public String hello() {
        i++;
        System.out.println("被調用..."+i);
        return "hello";
    }
}

配置文件application.yml

server:
  port: ${PORT:31001}
spring:
  application:
    name: ly-server01 #服務名,在下面的配置中作為實例名注冊到eureka中,其他程序調用服務時需要向eureka提供要調用的實例名,即這個名稱
eureka:
  client:
    fetch-registry: true #發現服務
    register-with-eureka: true #注冊服務
    service-url:
      defaultZone: ${EUREKA_server:http://localhost:50101/eureka/}  #eureka的地址
  instance:
    prefer-ip-address: true #將自己的IP注冊到eureka
    ip-address: ${IP_ADDRESS:127.0.0.1} #注冊的ip地址
    instance-id: ${spring.application.name}:${server.port} #注冊的實例名稱

啟動該服務,再次訪問localhost:50101,即可看到:

如此,服務便注冊成功了。

通過ribbon調用服務

ribbon是一個通過客戶端實現負載均衡的系統,它通過服務名向eureka請求可用的服務url,然后通過負載均衡的算法選擇一個可用的服務主機進行訪問,獲得結果;

建立另一個微服務子工程server02,和上述服務一樣,需要做成eureka客戶端,除此之外,還需要引入額外的依賴:

      <dependency>
            <groupId>com.squareup.okhttp3</groupId>
            <artifactId>okhttp</artifactId>
      </dependency>

另外,需要配置bean:

@Bean
@LoadBalanced // 這個注解是實現負載均衡的,如果不寫的話,就只能直接通過url訪問其他服務
public RestTemplate restTemplate() {
    return new RestTemplate(new OkHttp3ClientHttpRequestFactory());
}

配置文件同上面的一致;

另外將上server01工程開上兩份,開啟時通過設置jvm的參數-DPORT 來設置不同的端口,否則端口會沖突;

通過restTemplate調用hello接口:

@Autowired
RestTemplate restTemplate;
@Test
public void run() {
    for (int i = 0; i < 10; i++) {
    // 直接通過服務名調用接口 ResponseEntity
<String> forEntity = restTemplate.getForEntity("http://ly-server01/hello", String.class); String body = forEntity.getBody(); System.out.println(body); } }

上面調用了hello接口10次,對應於服務端,兩個注冊服務的服務分別被調用5次,這是因為默認的負載均衡的方式是輪詢,也就是依次調用可用的主機;

 

通過feign調用

feign客戶端調用遠程http接口,可以實現向調用本地接口方法那樣調用遠程服務,依舊是server02工程調用server01工程的服務;

在server02中添加依賴:

        <!--feign調用-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
        </dependency>
        <dependency>
            <groupId>com.netflix.feign</groupId>
            <artifactId>feign-okhttp</artifactId>
        </dependency>

在主函數上添加注解:@EnableFeignClients

在該工程下創建一個feign接口如下:

package cn.ly.client;

import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.RequestMapping;

@FeignClient("ly-server01") // feign客戶端注解,value是要調用的服務名,就是server01工程的服務名
public interface HelloClient {
// 注意一點,如果方法返回的是一個復雜對象類型,那么這個對象類型必須有無參構造器,否則會報錯 @RequestMapping(
"/hello") public String hello();// 這個方法和要調用的服務的接口方法書寫要一致,上面的url注意要書寫正確且完整,如果被調用的接口的controller類上也有url,那么在這里需要將其補全 }

然后在測試方法中將這個接口注入進去后,即可直接使用方法:

@Autowired
HelloClient helloClient;
@Test
public void run2() {
    for (int i = 0; i < 10; i++) {
        String hello = helloClient.hello();
        System.out.println(hello);
    }
}

上面依舊是調用了10次,分別在兩個開啟的server01工程中執行5次,輪詢的負載均衡;


免責聲明!

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



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