1. 程式人生 > 實用技巧 >springCloud 呼叫Python web 服務(sideCard)(轉)

springCloud 呼叫Python web 服務(sideCard)(轉)

原文請參考:https://blog.csdn.net/hliq5399/article/details/80540760

個人應用場景:

 使用python 實現一些演算法,然後通過java springboot 專案去呼叫。。。。

************************************

1.引言

說到Python這門語言,應該都會很熟悉,近幾年來Python大火,幾乎都到了人人喊著:“人生苦短,我學Python”的境地,確實Python在機器學習方面有著得天獨厚的優勢,在Python語言中擁有很多現成的機器學習函式庫,然後在Web開發中還是有著很多人使用Java

作為伺服器的後臺語言,尤其是近幾年來微服務的興起,也有著越來越多的人使用SpringCloud(基於Java語言實現的微服務框架),因此就產生了這麼一個需求:能否將Python的機器學習演算法整合到SpringCloud中,作為我們Web系統的服務,當我們自己使用Python實現了一個新的機器學習演算法的時候,可以同時為他人提供服務。使用者在Web端提供資料,而Web平臺提供演算法進行計算,同時反饋給使用者)。 要想實現上面的需求,其實就是存在著整合SpringCloud 整合Python的必要性。因此我查了SpringCloud的官網,還真的提供了整合Python語言的解決方案(其實是整合第三方語言的解決方案)。這個解決方案叫做:sidecar
。通過使用sidecar我們可以將Python介面註冊為SpringCloud的一個服務,實現Java(因為SpringCloudJava語言的一款框架)和Python的雙向通訊,即:Python可以呼叫Java語言的介面,同時Java也可以呼叫Python語言的介面。

2. 什麼是sidecar?

我們剛剛說了使用sidecar可以將SpringCloud和第三方語言整合,那什麼是sidecar呢?說白了sidecar就是springcloud提供的一個工具,使用該工具將第三方的rest介面整合到springcloud中來。那麼如何使用sidecar呢?首先我們看一下官網的描述。

2.1 Polyglot
支援Sidecar(官網描述)

Spring Cloud Netflix Sidecar 包含一個簡單的http api來獲取給定服務的所有例項(即主機和埠)。然後可以通過從Eureka獲取其路由條目的嵌入式Zuul代理來代理服務呼叫。可以通過主機查詢或通過Zuul代理訪問Spring Cloud Config伺服器。但是第三方程式必須執行健康檢查,以便Sidecar可以嚮應用程式啟動或關閉時向eureka報告(意思就是說:第三方程式必須提供一個介面告訴Spring Cloud自身是否還在執行?)。如何使用Sidecar呢?官網給出瞭如下的步驟:

2.1.1 使用Sidecar步驟

  • 新增Java包依賴

如果要在專案中包含Sidecar,需要使用org.springframework.cloudartifact id spring-cloud-netflix-sidecar的依賴。

  • 註解啟動Sidecar

使用@EnableSidecar建立Spring Boot應用程式。此註釋包括@EnableCircuitBreaker@EnableDiscoveryClient@EnableZuulProxy

  • 修改配置

配置Sidecar,應該將sidecar.portsidecar.health-uri新增到application.ymlsidecar.port屬性是非jvm應用程式正在偵聽的埠。這樣,Sidecar可以使用Eureka正確註冊該應用。sidecar.health-uri是可以在非jvm應用程式上訪問的,可以模擬Spring Boot健康指標。它應該返回一個json文件,如下所示:

  1. {
  2. "status":"UP"
  3. }

以下是Sidecar應用程式的application.yml示例:

  1. server:
  2. port: 5678
  3. spring:
  4. application:
  5. name: sidecar
  6. sidecar:
  7. port: 8000
  8. health-uri: http://localhost:8000/health.json

    2.1.2 Java呼叫非JVM程式介面

    我們使用Sidecar將第三方程式介面(比如Python)註冊到SpringCloud之中,如何使用Python介面呢?這時候就非常簡單了,此時我們就可以將Python介面當作Java介面進行呼叫(其實時通過springcloud去呼叫Sidecar,然後通過Sidecar去轉發我們的程式請求)。

    2.1.3 非JVM介面呼叫Java介面

    因為非JVM應用 被註冊到SpringCloud之中,對於第三方應用程式來說,整個SpringCloud的內容,我們都可以進行呼叫了,比如我們有一個Java服務叫做customers,那麼我們就可以通過url來呼叫,比如http://localhost:5678/customers(假設Sidecar在埠5678上),因為配置伺服器(configserver)也屬於SpringCloud的一個服務,因此非JVM語言也可以呼叫配置伺服器的配置,比如使用如下的urlhttp:// localhost:5678/configserver

    2.2 Sidecar總結

    看了官網的描述,似乎我們還是抓不住重點,到底應該如何結合Sidecar和第三方程式呢?依舊是如此的茫然。下面我著重說一下官網提供的重點:

    • Sidecar是一個用於監聽非JVM應用程式(可以是Python或者Node或者Php等等)的一個工具,通過Sidecar可以實現Java和第三方應用程式的雙向互動
    • 第三方應用程式必須要實現一個介面,實時向Sidecar報告自己的狀態,告訴Sidecar自己還在執行著。
    • Sidecar應用程式必須和第三方應用程式執行在同一臺電腦上,也就是說他們之間是localhost,不能是ip訪問(官網未提及)

sideCard 服務依賴:

    <properties>
        <java.version>1.8</java.version>
        <spring.cloud.version>Finchley.RC2</spring.cloud.version>
    </properties>

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

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>

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

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

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-netflix-sidecar</artifactId>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
View Code

定義sidecar:(不用寫任何程式碼)

main方法

@EnableSidecar
@SpringBootApplication
public class PySidecarApplication {
 
    public static void main(String[] args) {
        SpringApplication.run(PySidecarApplication.class, args);
    }
}

application.properties配置檔案

spring.application.name=py-sidecar
server.port=8001
sidecar.port=3000
sidecar.health-uri=http://localhost:${sidecar.port}/health   #Python 服務的mock 健康檢測
hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds=10000
ribbon.ConnectTimeout=5000
ribbon.ReadTimeout=5000
eureka.client.serviceUrl.defaultZone=http://localhost:8000/eureka/

python 服務:

import json
from flask import Flask, Response
app = Flask(__name__)
@app.route("/health")
def health():
    result = {'status': 'UP'}
    return Response(json.dumps(result), mimetype='application/json')
@app.route("/getUser")
def getUser():
    result = {'username': 'python', 'password': 'python'}
    return Response(json.dumps(result), mimetype='application/json')
app.run(port=3000, host='0.0.0.0')

這樣sideCard 服務就有python 服務的所有介面了,接下來就可以使用  RestTemplate  或是 spring-cloud-starter-openfeign 來使用這寫介面

Sidecar應用程式必須和第三方應用程式執行在同一臺電腦上,也就是說他們之間是localhost,不能是ip訪問,測試發現如果不在同一臺機器上,會報錯:連線誒拒絕

使用:略