前言
该篇文章分享如何将Python Web
服务融入到Spring Cloud微服务体系中,并调用其服务,Python Web框架用的是Flask
方案
Sidecar
+ Flask
,在这里,我们会使用Sidecar
将Python
接口注册到SpringCloud
中,将Python
接口当作Java
接口进行调用(通过SpringCloud
去调用Sidecar
,然后通过Sidecar
去转发我们的程序请求)
Sidecar
是SpringCloud
提供的一个可将第三方的rest
接口集成到SpringCloud
中的工具
Python服务
manage.py
import json from flask import Flask, Response, request, make_response, jsonify 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.errorhandler(404) def not_found(error): return make_response(jsonify({'error': 'Not found'}), 404) if __name__ == "__main__": app.run(host="0.0.0.0", port=3000)
大致说下上述代码,Python
服务监听3000
端口,health
方法用于给Sidecar
提供健康接口,用于实时向Sidecar
提供自己的健康状态,getUser
是Python
向外界提供的服务
- 运行方式
python manage.py runserver
sidecar工程
- 添加依赖
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-eureka</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-netflix-sidecar</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency>
SidecarApplication.java
import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.netflix.sidecar.EnableSidecar; @EnableSidecar @SpringBootApplication public class SidecarApplication { public static void main(String[] args) { SpringApplication.run(SidecarApplication.class, args); } }
application.yml
spring: profiles: active: "dev" application: name: demo-sidecar sidecar: port: 3000 health-uri: http://localhost:${sidecar.port}/health ribbon: ConnectTimeout: 50000 ReadTimeout: 50000 hystrix: command: default: execution: isolation: thread: timeoutInMilliseconds: 10000 server: port: 8326 eureka: client: healthcheck: enabled: true service-url: defaultZone: http://${registry.host:localhost}:${registry.port:8761}/eureka/ registry: host: localhost port: 31091
大致说下上述代码,main
方法要使用@EnableSidecar
注解,sidecar port
代表监听Python
运行的端口,server port
代表Sidecar
运行的端口,spring application name
代表Sidecar
的服务名,sidecar health-uri
是Python
健康接口,指向python的健康服务
服务调用 - DemoServer工程(端口8325)
调用方式一 : RestTemplate
- DemoServerApplication.java
@SpringBootApplication public class DemoServerApplication { public static void main(String[] args) { SpringApplication.run(DemoServerApplication.class, args); } @Bean @LoadBalanced RestTemplate restTemplate() { return new RestTemplate(); } }
RestTemplateController.java
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 RestTemplateController { @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://demo-sidecar/getUser", String.class).getBody(); // return restTemplate.getForEntity("http://localhost:3000/getUser", String.class).getBody(); } }
- 这里做下说明,
@LoadBalanced
用于开启负载均衡,在这里有两种调用方式,使用和不使用@LoadBalanced
- 使用
@LoadBalanced
注解后,RestTemplate
可以直接调用服务名
@Bean @LoadBalanced RestTemplate restTemplate() { return new RestTemplate(); } ++++++++++++++++++++++++++++++ return restTemplate.getForEntity("http://demo-sidecar/getUser", String.class).getBody();
- 不使用
@LoadBalanced
注解,RestTemplate
调用的就是固定的IP+PORT
@Bean // @LoadBalanced RestTemplate restTemplate() { return new RestTemplate(); } ++++++++++++++++++++++++++++++ return restTemplate.getForEntity("http://localhost:3000/getUser", String.class).getBody();
- 服务的启动顺序:Python服务,注册中心,sidecar工程,DemoServer工程
- 运行结果
调用方式二: Feign
congfig
类中需添加注解@EnableFeignClients
,具体使用请百度SidecarController.java
@RestController public class SidecarController { private SidecarAPIClient sidecarAPIClient; @Autowired public SidecarController(SidecarAPIClient sidecarAPIClient) { this.sidecarAPIClient = sidecarAPIClient; } @GetMapping("/getUser") public Object getUser() { return this.sidecarAPIClient.getUser(); } }
SidecarAPIClient.java
@FeignClient(name="demo-sidecar", configuration = FeignConfigure.class) public interface SidecarAPIClient { @GetMapping("/getUser") Object getUser(); }
FeignConfigure.java
import feign.Logger; import feign.codec.Encoder; import feign.form.spring.SpringFormEncoder; import org.springframework.beans.factory.ObjectFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.web.HttpMessageConverters; import org.springframework.cloud.netflix.feign.support.SpringEncoder; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration public class FeignConfigure { @Bean Logger.Level feignLoggerLevel() { return Logger.Level.FULL; } @Autowired private ObjectFactory<HttpMessageConverters> messageConverters; @Bean public Encoder feignFormEncoder() { return new SpringFormEncoder(new SpringEncoder(messageConverters)); } }
- 服务的启动顺序:Python服务,注册中心,sidecar工程,DemoServer工程
- 调用结果
至此,已完成微服务调用Python Web服务
Sidecar总结
Sidecar
是一个用于监听非JVM应用程序(可以是Python
或者Node
或者Php
等等)的一个工具,通过Sidecar
可以实现Java
和第三方应用程序的双向交互- 第三方应用程序必须要实现一个接口,实时向
Sidecar
报告自己的状态,告诉Sidecar
自己还在运行着。 Sidecar
应用程序必须和第三方应用程序运行在同一台电脑上,也就是说他们之间是localhost
,不能是IP
访问
参考博客
SpringCloud 整合Python 感谢大佬
end
来源:https://www.cnblogs.com/maggieq8324/p/12099849.html