基于Thirft的实践笔记——java后台调用python深度学习算法脚本

前言

本文的"客户端"“服务端”之称是针对rpc的服务调用而称,服务提供者称作“服务端”, 服务调用者称作"客户端"。
本文是对pytorch框架训练好的模型,提供一个web后台去调用的一次实践。
深度学习用到的技术栈是python的pytorch,web后台是java的springboot。由于做这个的时候作者的java基础一般,没考虑更多的并发or服务发现的一些东西,代码比较简陋。未来等作者知识储备丰富了再回来考虑修改。

1. 使用thrift做rpc

windows 下载地址
下载后随便放到一个目录比如 C://Thrift,在环境变量Path中加入 C://Thrift;

1.1. java导入依赖

<dependency>
    <groupId>org.apache.thrift</groupId>
    <artifactId>libthrift</artifactId>
    <version>0.10.0</version>
</dependency>

1.2. python导入依赖

windows版:
官网源码下载,解压后进入thrift-0.10.0/lib/py执行:

python setup.py install

linux版:

1.3. 编写thrift文件 analyze_service.thrift

service AnalyzeService {
    string analyzeImage(1:string imageName)
}

打开cmd,执行

thrift --gen py analyze_service.thrift
thrift --gen java analyze_service.thrift

1.4. python做服务端

"""
-------------------------------------------------
   Author :        lin
   date:          2019/8/24 22:14
-------------------------------------------------
"""
__author__ = 'lin'


import torch
import os
from analyze_service import AnalyzeService

from thrift.transport import TSocket
from thrift.transport import TTransport
from thrift.protocol import TBinaryProtocol
from thrift.server import TServer
from net.classify import load_net, imgPathToTensor, classify

__HOST = '172.18.0.4'
__PORT = 3049


model = load_net()


class AnalyzeImageHandler(object):
    def analyzeImage(self, imageName):
        '''
        :param imageName: 一张或多张图片路径, 分号隔开
        :return: 分析结果
        '''
        for index, img in enumerate(imageName):
            if index == 0:
                inputs = imgPathToTensor(img)
            else:
                inputs = torch.cat((inputs, imgPathToTensor(img)), 0)
        return classify(inputs, model)

if __name__ == '__main__':
    print("===================== start server =====================")
    handler = AnalyzeImageHandler()

    processor = AnalyzeService.Processor(handler)
    transport = TSocket.TServerSocket(__HOST, __PORT)
    tfactory = TTransport.TBufferedTransportFactory()
    pfactory = TBinaryProtocol.TBinaryProtocolFactory()

    rpcServer = TServer.TForkingServer(processor, transport, tfactory, pfactory)
    rpcServer.serve()

1.5. java做客户端

package cn.gpnu.qtyy.service;

import org.apache.thrift.TException;
import org.apache.thrift.protocol.TBinaryProtocol;
import org.apache.thrift.protocol.TProtocol;
import org.apache.thrift.transport.TSocket;
import org.apache.thrift.transport.TTransport;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.util.List;

/**
 * cn.gpnu.qtyy.service.ThriftClient class
 * <p>
 *
 * </p>
 *
 * @author Lin Xiaopeng
 * @date 2019/8/24
 */
@Component
public class ThriftClient {
    @Value("${spring.pythonserver.host}")
    private String host;

    @Value("${spring.pythonserver.port}")
    private Integer port;

    public String startClient(List<String> imageName) {
        TTransport transport;
        String result = "";
        try {
            transport = new TSocket(host, port);
            TProtocol protocol = new TBinaryProtocol(transport);
            AnalyzeService.Client client = new AnalyzeService.Client(protocol);
            transport.open();
            result = client.analyzeImage(imageName);
            transport.close();
            return result;
        } catch (TException e) {
            e.printStackTrace();
            return e.getMessage();
        }
    }
}

2. 使用docker

2.1. pom.xml 添加依赖

<properties>
    <docker.image.prefix>springboot</docker.image.prefix>
</properties>
<plugin>
    <groupId>com.spotify</groupId>
    <artifactId>docker-maven-plugin</artifactId>
    <version>1.0.0</version>
    <configuration>
        <imageName>${docker.image.prefix}/${project.artifactId}</imageName>
        <dockerDirectory>src/main/docker</dockerDirectory>
        <resources>
            <resource>
                <targetPath>/</targetPath>
                <directory>${project.build.directory}</directory>
                <include>${project.build.finalName}.jar</include>
            </resource>
        </resources>
    </configuration>
</plugin>

2.2. 编辑Dockerfile

FROM java:8
EXPOSE 3048
ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/data/qtyy.jar"]
FROM python:3.7
EXPOSE 3049
ADD ./requirements.txt /code/requirements.txt
RUN pip install numpy
RUN pip install --pre torch torchvision -f https://download.pytorch.org/whl/nightly/cpu/torch_nightly.html
RUN pip install thrift==0.10.0
RUN pip install dropblock
ENTRYPOINT ["python", "/code/gen-py/main.py"]

2.3. 构建镜像

进入Drockerfile所在目录

docker build -t springboot_qtyy_images .

docker build -t deeplearning_images .

2.4. 创建并启动容器

docker run --network bridge --name springboot_qtyy -it -v /var/www/target:/data -d -p 3048:3048 springboot_qtyy_images
docker run --network bridge --name deeplearning -it -v /var/www/deeplearning:/code -d -p 3049:3049 deeplearning_images

2.5. 创建一个桥接网络

下面的localNet是网络名字,可自行修改;关于192.168.0.0这个子网,也可以自行定义.
默认按照下面的命令,执行后将可以通过192.168.0.1访问宿主机.

docker network create -d bridge --subnet 192.168.0.0/24 --gateway 192.168.0.1 localNet

  • 3
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Java是一种广泛使用的面向对象的编程语言,由Sun Microsystems公司于1995年5月正式发布。它的设计目标是“一次编写,到处运行(Write Once, Run Anywhere)”,这意味着开发者可以使用Java编写应用程序,并在支持Java的任何平台上无需重新编译即可运行,这得益于其独特的跨平台性,通过Java虚拟机(JVM)实现不同操作系统上的兼容。 Java的特点包括: 面向对象:Java全面支持面向对象的特性,如封装、继承和多态,使得代码更易于维护和扩展。 安全:Java提供了丰富的安全特性,如禁止指针运算、自动内存管理和异常处理机制,以减少程序错误和恶意攻击的可能性。 可移植性:Java字节码可以在所有安装了JVM的设备上执行,从服务器到嵌入式系统,再到移动设备和桌面应用。 健壮性与高性能:Java通过垃圾回收机制确保内存的有效管理,同时也能通过JIT编译器优化来提升运行时性能。 标准库丰富:Java拥有庞大的类库,如Java SE(Java Standard Edition)包含基础API,用于开发通用应用程序;Java EE(Java Enterprise Edition)提供企业级服务,如Web服务、EJB等;而Java ME(Java Micro Edition)则针对小型设备和嵌入式系统。 社区活跃:Java有着全球范围内庞大的开发者社区和开源项目,持续推动技术进步和创新。 多线程支持:Java内建对多线程编程的支持,使并发编程变得更加简单直接。 动态性:Java可以通过反射、注解等机制实现在运行时动态加载类和修改行为,增加了程序的灵活性。 综上所述,Java凭借其强大的特性和广泛的适用范围,在企业级应用、互联网服务、移动开发等领域均扮演着举足轻重的角色,是现代软件开发不可或缺的重要工具之一。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值