SpringCloud 整合Python

xiaoxiao2025-11-18  3

转自: https://blog.csdn.net/hliq5399/article/details/80540760引言什么是sidecar 1 Polyglot支持Sidecar官网描述 11 使用Sidecar步骤12 Java调用非JVM程序接口13 非JVM接口调用Java接口2 Sidecar总结Python和SpringCloud整合实例 1 定义Python服务2 定义SpringCloud注册中心3 定义sidecar4 定义Java服务5 服务相互调用 51 调用Java原生服务52 Java调用Python服务53 通过sidecar调用Java服务6 实例代码的下载地址

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(因为SpringCloud是Java语言的一款框架)和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.cloud和artifact id spring-cloud-netflix-sidecar的依赖。

注解启动Sidecar

使用@EnableSidecar创建Spring Boot应用程序。此注释包括@EnableCircuitBreaker,@EnableDiscoveryClient和@EnableZuulProxy。

修改配置

配置Sidecar,应该将sidecar.port和sidecar.health-uri添加到application.yml。sidecar.port属性是非jvm应用程序正在侦听的端口。这样,Sidecar可以使用Eureka正确注册该应用。sidecar.health-uri是可以在非jvm应用程序上访问的,可以模拟Spring Boot健康指标。它应该返回一个json文档,如下所示:

 

{

"status":"UP"

}

以下是Sidecar应用程序的application.yml示例:

 

server:

port: 5678

spring:

application:

name: sidecar

 

sidecar:

port: 8000

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语言也可以调用配置服务器的配置,比如使用如下的url: http:// localhost:5678/configserver

2.2 Sidecar总结

      看了官网的描述,似乎我们还是抓不住重点,到底应该如何结合Sidecar和第三方程序呢?依旧是如此的茫然。下面我着重说一下官网提供的重点:

Sidecar是一个用于监听非JVM应用程序(可以是Python或者Node或者Php等等)的一个工具,通过Sidecar可以实现Java和第三方应用程序的双向交互第三方应用程序必须要实现一个接口,实时向Sidecar报告自己的状态,告诉Sidecar自己还在运行着。Sidecar应用程序必须和第三方应用程序运行在同一台电脑上,也就是说他们之间是localhost,不能是ip访问(官网未提及)

3.Python和SpringCloud整合实例

      前面说了这么多理论性的东西,似乎我们只知道了一个事情:通过Sidecar可以实现SpringCloud和第三方应用程序的整合,就比如我们的Python,可以利用Sidecar将Python集成到我们的微服务中来,然后我们就可以利用Python强大的机器学习算法了。

      说了这么多,往往不如一个实例来的更加直接,现在我就使用Python来和SpringCloud整合。在我的程序结构如下所示:

python接口中会提供一个服务功能:获取Python用户名和密码,用户名为:python,密码为python。同时python应该还提供一个健康接口,报告自己的健康状态Java服务会提供两个接口(JavaUser,PythonUser),JavaUser方法用于获得Java用户名和密码,用户名为:java,密码为java。PythonUser方法会调用python服务,获得Python用户名和密码。

3.1 定义Python服务

      在Python中,我使用flask提供Web服务,代码如下:

 

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')

代码解释:

Python服务监听3000接口health方法用于给Sidecar提供健康接口,用于实时向Sidecar提供自己的健康状态。getUser是Python向外界提供的服务,提供Python用户的用户名和密码

3.2 定义SpringCloud注册中心

application.properties配置文件

 

server.port=8000

spring.application.name=eureka-server

eureka.client.serviceUrl.defaultZone=http://localhost:${server.port}/eureka/

eureka.client.registerWithEureka=false

eureka.client.fetchRegistry=false

main方法

 

package com.example.demo;

 

import org.springframework.boot.SpringApplication;

import org.springframework.boot.autoconfigure.SpringBootApplication;

import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;

 

@EnableEurekaServer

@SpringBootApplication

public class DemoApplication {

 

public static void main(String[] args) {

SpringApplication.run(DemoApplication.class, args);

}

}

代码解释:

注册中心启动端口:8000

3.3 定义sidecar

main方法

 

package com.example.demo;

import org.springframework.boot.SpringApplication;

import org.springframework.boot.autoconfigure.SpringBootApplication;

import org.springframework.cloud.netflix.sidecar.EnableSidecar;

@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

hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds=10000

ribbon.ConnectTimeout=5000

ribbon.ReadTimeout=5000

eureka.client.serviceUrl.defaultZone=http://localhost:8000/eureka/

代码解释:  * main方法使用了@EnableSidecar注解  * sidecar.port代表第三方程序运行的端口(比如上方的Python),所以监听端口为3000  * server.port代表sidecar运行的端口  * spring.application.name代表sidecar的应用名字(后面要用到)  * sidecar.health-uri是Python健康接口,应指向python的健康服务

3.4 定义Java服务

Java服务

 

package com.example.demo;

import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.web.bind.annotation.RequestMapping;

import org.springframework.web.bind.annotation.RestController;

import org.springframework.web.client.RestTemplate;

@RestController

public class JavaController {

@Autowired

private RestTemplate restTemplate;

@RequestMapping("/java-user")

public String JavaUser() {

return "{'username': 'java', 'password': 'java'}" ;

}

@RequestMapping("/python-user")

public String PythonUser() {

return restTemplate.getForEntity("http://py-sidecar/getUser", String.class).getBody();

}

 

}

main方法

 

package com.example.demo;

import org.springframework.boot.SpringApplication;

import org.springframework.boot.autoconfigure.SpringBootApplication;

import org.springframework.cloud.client.SpringCloudApplication;

import org.springframework.cloud.client.loadbalancer.LoadBalanced;

import org.springframework.context.annotation.Bean;

import org.springframework.web.client.RestTemplate;

@SpringCloudApplication

public class RibbonConsumerApplication {

@Bean

@LoadBalanced

RestTemplate restTemplate() {

return new RestTemplate();

}

public static void main(String[] args) {

SpringApplication.run(RibbonConsumerApplication.class, args);

}

}

application.properties

 

spring.application.name=java-service

server.port=8002

eureka.client.service-url.defaultZone=http://localhost:8000/eureka/

代码解释:

server.port代表Java服务运行的端口spring.application.name代表Java服务应用的名字(后面要用到)在PythonUser方法中,Java调用了Python服务,将Python用户返回(注意:在这里Java语言调用了Python的接口,实现了Java和Python的通信)在JavaUser方法中,直接返回了Java用户的信息

3.5 服务相互调用

      在服务调用之前,我们先回顾一下代码都做了什么样子的事情:

定义了一个Python服务,运行在端口3000定义了一个sidecar,运行在短就8001,监听Python端口3000,应用名字为py-sidecar定义了一个Java服务,运行在端口8002,应用名字为java-service服务的启动顺序:Python服务,注册中心,py-sidecar,java-service

3.5.1 调用Java原生服务

      对于Java原生服务的调用没有什么特别,直接访问URL即可,如:http://localhost:8002/java-user

3.5.2 Java调用Python服务

      在java-service服务的PythonUser中,Java调用了Python的服务,使用restTemplate模板,通过:http://{service_id}/{method}实现了对Python服务的调用(这里我们调用的时Java的端口,返回的是Python的数据内容)

3.5.3 通过sidecar调用Java服务

      我们使用了sidecar,所以我们可以使用sidecar实现对Java服务的调用,比如:http://{host}:{port}/{service_id}/{method},其中:

host是sidecar的主机地址port是sidecar的端口地址service_id是Java服务的idmethod是Java服务的具体方法地址

      如果我们想通过sidecar获得Java用户的对象,可以这么写:http://localhost:8001/java-service/java-user

3.6 实例代码的下载地址

的下载地址为:SpringCloud整合python码云的下载地址为:SpringCloud整合python(如果从码云下载代码,麻烦给小Demo一个Star,您的支持是我最大的动力)
转载请注明原文地址: https://www.6miu.com/read-5039845.html

最新回复(0)