springCloud整合python基于springBoot2.0.2

1背景

最近需求需要将一些python项目整合到web,项目架构基于springCloud。

通过sidecar将springCloud和第三方语言整合。Sidecar将第三方程序接口注册到SpringCloud中,然后就可以将第三方接口当作Java接口进行调用(通过springCloud去调用Sidecar,然后通过Sidecar转发程序请求)。

Sidecar是一个用于监听非JVM应用程序的一个工具,通过Sidecar可以实现Java和第三方程序的双向交互。(第三方程序必须要实现一个接口,实时向Sidecar报告自己的状态,告诉Sidecar自己还活着)。

Sidecar应用程序必须和第三方应用程序运行在同一个电脑上。

Spring Cloud Netflix Sidecar通过的http api来获取给定服务的所以实例(主机和端口)。然后通过Eureka获取路由条目的嵌入式Zuul代理来代理服务调用。通过主机查找或通过Zuul代理访问Spring Cloud Config服务器。但是第三方必须执行健康检查,以便Scar可以向应用程序启动或关闭时向eureka报告。

2Sidecar使用步骤

step1.添加java包依赖

org.springframework.cloud和artifact id spring-cloud-netflix-sidecar

step2.注解启动Sidecar

@EnableSidecar创建Sping boot应用程序。此注释包括@EnableCircuitBreaker,@EnableDiscoveryClient和@EnableZuulProxy

step3.修改配置

配置Sidecar,应该将Sidecar.port和sidecar.health-uri添加到application.properties。

sidecar.port属性是非jvm应用程序正在侦听的端口。这样,Sidecar可以使用Eureka正确注册应用。

sidecar.health-uri是可以在非jvm应用程序上访问的,可以模拟Spring Boot健康指标。它返回一个json文档

{

"status":"up"

}

Sidecar应用的application.propertie

3定义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')

Python服务监听3000接口。

health方法用于给Sidecar提供健康接口,实时向Sidecar提供自己的健康状态。

getUser是Python向外界提供的服务。例子接口

 

<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">
    <groupId>com.demo</groupId>
    <artifactId>cloud</artifactId>
    <packaging>pom</packaging>
    <version>1.0-SNAPSHOT</version>
	<description>springCloud学习</description>

	<!-- 指定spring boot版本 -->
	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>2.0.3.RELEASE</version>
		<relativePath />
		<!-- lookup parent from repository -->
	</parent>

	<!-- 指定spring cloud版本和jdk版本 -->
	<properties>
		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
		<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
		<java.version>1.8</java.version>
		<spring-cloud.version>Finchley.RELEASE</spring-cloud.version>
	</properties>

	<!-- 引入 spring-cloud模块 -->
	<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>
		<!-- 引入 spring-boot测试模块 -->
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-test</artifactId>
			<scope>test</scope>
		</dependency>
	</dependencies>

	<build>
		<plugins>
			<!-- 引入 spring-boot插件模块 -->
			<plugin>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-maven-plugin</artifactId>
			</plugin>
		</plugins>
	</build>
	<repositories>
		<repository>
			<id>spring-milestones</id>
			<name>Spring Milestones</name>
			<url>https://repo.spring.io/milestone</url>
			<snapshots>
				<enabled>false</enabled>
			</snapshots>
		</repository>
	</repositories>
	<modules>
	    <module>registry</module>
        <module>auth</module>
        <module>sidecar</module>

	</modules>
</project>

4定义注册中心

maven

<?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>
    <packaging>jar</packaging>
    <artifactId>registry</artifactId>
    <description>euraka project for Spring Boot</description>
    <parent>
        <artifactId>cloud</artifactId>
        <groupId>com.demo</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <java.version>1.8</java.version>
        <docker.image.prefix>spring-boot</docker.image.prefix>
    </properties>
    <dependencies>
        <!--<dependency>-->
            <!--<groupId>org.springframework.boot</groupId>-->
            <!--<artifactId>spring-boot-starter-web</artifactId>-->
        <!--</dependency>-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
            <version>2.0.0.RELEASE</version>
        </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-netflix-eureka-server</artifactId>
            <version>RELEASE</version>
            <scope>compile</scope>
        </dependency>
    </dependencies>
    <build>
        <plugins>
            <plugin>
                <artifactId>maven-compiler-plugin</artifactId>
                <configuration>
                    <source>${java.version}</source>
                    <target>${java.version}</target>
                    <fork>true</fork>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <!--<executable>true</executable>-->
                    <fork>true</fork>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.mybatis.generator</groupId>
                <artifactId>mybatis-generator-maven-plugin</artifactId>
                <version>1.3.6</version>
                <configuration>
                    <configurationFile>
                        ${basedir}/src/main/resources/generator/generatorConfig.xml
                    </configurationFile>
                    <overwrite>true</overwrite>
                    <verbose>true</verbose>
                </configuration>
                <dependencies>
                    <dependency>
                        <groupId>mysql</groupId>
                        <artifactId>mysql-connector-java</artifactId>
                        <version>5.1.29</version>
                    </dependency>
                    <dependency>
                        <groupId>tk.mybatis</groupId>
                        <artifactId>mapper</artifactId>
                        <version>4.0.0</version>
                    </dependency>
                    <dependency>
                        <groupId>com.lpty</groupId>
                        <artifactId>common-dao</artifactId>
                        <version>1.0-SNAPSHOT</version>
                    </dependency>
                </dependencies>
            </plugin>
 
    </build>
    <repositories>
        <repository>
            <id>spring-snapshots</id>
            <name>Spring Snapshots</name>
            <url>https://repo.spring.io/snapshot</url>
            <snapshots>
                <enabled>true</enabled>
            </snapshots>
        </repository>
        <repository>
            <id>spring-milestones</id>
            <name>Spring Milestones</name>
            <url>https://repo.spring.io/milestone</url>
            <snapshots>
                <enabled>false</enabled>
            </snapshots>
        </repository>
    </repositories>
</project>

配置

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.eureka;

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


@SpringBootApplication
@EnableEurekaServer
public class EurekaApplication {

	public static void main(String[] args) {
		SpringApplication.run(EurekaApplication.class, args);
	}
}

注册中心端口:8000

5定义sidecar

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>
    <packaging>jar</packaging>
    <artifactId>sidecar</artifactId>
    <parent>
        <artifactId>cloud</artifactId>
        <groupId>com.lpty</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <java.version>1.8</java.version>
        <spring-cloud.version>Finchley.BUILD-SNAPSHOT</spring-cloud.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</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>
    </dependencies>
    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>Finchley.RELEASE</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

配置

spring.application.name=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/

sidecar.port代表第三方程序运行端口(比如上方python),所以监听端口为3000

server.port代表sidecar运行端口

spring.application.name=sidecar代表sidecar应用名字

sidecar.health-uri是python的健康接口。

main方法

package com.example.sidecar;

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);
    }
}

6.定义Java服务

spring.application.name=java-service
server.port=8888
eureka.client.service-url.defaultZone=http://localhost:8000/eureka/
  • server.port代表Java服务运行的端口
  • spring.application.name代表Java服务应用的名字

controller

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://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);
    }
}

在调用服务之前,回顾下代码做了什么事情:

定义了一个python服务,运行在端口3000

定义一个sidecar,运行在端口8001,监听python端口3000,应用名字为sidecar

定义一个JAVA服务,运行在端口8888,应用名字为java-service

启动Python服务,注册中心,sidecar,java-service

猜你喜欢

转载自blog.csdn.net/Fichz/article/details/81098179