(1)SpringCloud 整合Python

文章目录

  • 1.引言
  • 2. 什么是`sidecar`?
    • 2.1 `Polyglot`支持`Sidecar`(官网描述)
      • 2.1.1 使用`Sidecar`步骤
      • 2.1.2 Java调用非JVM程序接口
      • 2.1.3 非JVM接口调用Java接口
    • 2.2 `Sidecar`总结
  • 3.`Python`和`SpringCloud`整合实例
    • 3.1 定义Python服务
    • 3.2 定义`SpringCloud`注册中心
    • 3.3 定义`sidecar`
    • 3.4 定义Java服务
    • 3.5 服务相互调用
      • 3.5.1 调用Java原生服务
      • 3.5.2 Java调用Python服务
      • 3.5.3 通过`sidecar`调用`Java`服务
    • 3.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(因为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文档,如下所示:

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

2.2 Sidecar总结

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

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

3.PythonSpringCloud整合实例

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

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

  • python接口中会提供一个服务功能:获取Python用户名和密码,用户名为:python,密码为python。同时python应该还提供一个健康接口,报告自己的健康状态
  • Java服务会提供两个接口(JavaUser,PythonUser)JavaUser方法用于获得Java用户名和密码,用户名为:java,密码为javaPythonUser方法会调用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提供自己的健康状态。
  • getUserPython向外界提供的服务,提供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-uriPython健康接口,应指向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的接口,实现了JavaPython的通信)**
  • JavaUser方法中,直接返回了Java用户的信息

3.5 服务相互调用

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

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

3.5.1 调用Java原生服务

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

(1)SpringCloud 整合Python_第1张图片

3.5.2 Java调用Python服务

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

(1)SpringCloud 整合Python_第2张图片

3.5.3 通过sidecar调用Java服务

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

  • hostsidecar的主机地址
  • portsidecar的端口地址
  • service_idJava服务的id
  • methodJava服务的具体方法地址

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

(1)SpringCloud 整合Python_第3张图片

3.6 实例代码的下载地址

  • CSDN的下载地址为:SpringCloud整合python
  • GitHub的下载地址为:SpringCloud整合python(如果从码云下载代码,麻烦给小Demo一个Star,您的支持是我最大的动力)

你可能感兴趣的:(Java之框架)