基于Kubernetes、Docker的机器学习微服务系统设计 | |||||
---|---|---|---|---|---|
实践篇 | (1)概念与构想 | (二)架构与部署 | (三)微服务框架 | (四)中文分词 | (五)预处理 |
(六)特征选择 | (七)分类器微 | (八)部署配置 | (九)应用服务 | (十)数据可视化 | |
研究篇 | RS中文分词 | MP特征选择 | NLV文本分类 | 快速kNN | 文本分类 |
为了微服务的接口交互统一,本系统采用统一的框架模式。采用Jersey软件框架,Jersey 是开源的RESTful框架, 实现了JAX-RS (JSR 311 & JSR 339) 规范。
微服务框架
RESTful框架实现流程如图所示:

高层次的适配器模式的应用,将业务服务与RESTful通信解耦,业务仅关注自己的实现。
框架实现
配置文件config.properties内容如下:
#restful API config
listen.ip=0.0.0.0
listen.port=8084
#thread pool config
thread.core.pool.size=4
thread.max.pool.size=4
#mirco server config
mircoServer.name=business
jar.path=file:business-1.0.jar
jar.actionClass=com.robin.action.BusinessAction
#log config
log.path=log/
log.prefix=business
# Level.ALL Level.FINEST Level.FINER Level.FINE Level.CONFIG
# Level.INFO Level.WARNING Level.SEVERE Level.OFF
log.level=Level.INFO
log.file.limit=1048576
log.file.count=3
通用资源类:
/**
* <DT><B>描述:</B></DT>
* <DD>通用资源类</DD>
*
* @version Version1.0
* @author Robin
* @version <I> V1.0 Date:2018-05-21</I>
* @author <I> E-mail:xsd-jj@163.com</I>
*/
@Path("robin")
public class CommonResource {
// 日志
private static final Logger LOGGER = RobinLogger.getLogger();
// 微服务
private static MircoServiceAction mircoServer;
// 配置的微服务名称
private static final String CFG_MS_NAME;
static {
// 微服务名称配置文件检查
CFG_MS_NAME = ConfigUtil.getConfig("mircoServer.name");
String jarPath = ConfigUtil.getConfig("jar.path");
URL url = null;
try {
url = new URL(jarPath);
} catch (MalformedURLException ex) {
LOGGER.log(Level.SEVERE, ex.getMessage());
}
URLClassLoader classLoader = new URLClassLoader(new URL[]{url}, Thread.currentThread()
.getContextClassLoader());
Class<?> actionClass = null;
try {
String actionClassName = ConfigUtil.getConfig("jar.actionClass");
actionClass = (Class<?>) classLoader.loadClass(actionClassName);
} catch (ClassNotFoundException ex) {
LOGGER.log(Level.SEVERE, ex.getMessage());
}
if (null == actionClass) {
LOGGER.log(Level.SEVERE, "actionClass is null");
System.exit(-1);
}
try {
mircoServer = (MircoServiceAction) actionClass.newInstance();
} catch (InstantiationException | IllegalAccessException ex) {
LOGGER.log(Level.SEVERE, ex.getMessage());
}
}
/**
* Method handling HTTP GET requests. The returned object will be sent to
* the client as "application/json" media type.
*
* @return String that will be returned as a application/json response.
*/
@GET
@Produces(MediaType.TEXT_PLAIN)
public String getIt() {
String cfgMsName = ConfigUtil.getConfig("mircoServer.name");
return "Micro server [" + cfgMsName + "] is running...\n";
}
@POST
@Path("{microService}")
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
public JSONObject requestService(
@PathParam("microService") String serverName,
JSONObject reqJson) {
JSONObject rspJson = null;
if (!serverName.equals(CFG_MS_NAME)) {
rspJson = new JSONObject();
try {
rspJson.put("status", "ERROR");
rspJson.put("msg", "Mirco server name [" + serverName + "] error.");
} catch (JSONException ex) {
LOGGER.log(Level.SEVERE, ex.getMessage());
}
return rspJson;
}
if (null != mircoServer) {
rspJson = (JSONObject) mircoServer.action(reqJson);
}
return rspJson;
}
}
Restful服务类:
/**
* <DT><B>描述:</B></DT>
* <DD>Restful服务类</DD>
*
* @version Version1.0
* @author Robin
* @version <I> V1.0 Date:2018-05-22</I>
* @author <I> E-mail:xsd-jj@163.com</I>
*/
public class RestfulServer {
private static final Logger LOGGER = RobinLogger.getLogger();
private static URI uri;
private static HttpServer server;
public static HttpServer getServer() {
return server;
}
public static URI getUri() {
if (null == uri) {
String listenAddr = ConfigUtil.getConfig("listen.ip");
String listenPort = ConfigUtil.getConfig("listen.port");
String baseUri = "http://" + listenAddr + ":" + listenPort + "/";
uri = URI.create(baseUri);
}
return uri;
}
/**
* Starts Grizzly HTTP server exposing JAX-RS resources defined in this application.
*
*/
public static void startServer() {
// create a resource config that scans for JAX-RS resources and providers
// in com.robin.restful package
final ResourceConfig rc = new ResourceConfig();
rc.packages("com.robin.restful");
rc.register(JettisonFeature.class);
// create and start a new instance of grizzly http server
// exposing the Jersey application at URI
// return GrizzlyHttpServerFactory.createHttpServer(URI.create(BASE_URI), rc);
server = GrizzlyHttpServerFactory.createHttpServer(getUri(), rc);
String corePoolSizeStr = ConfigUtil.getConfig("thread.core.pool.size");
String maxPoolSizeStr = ConfigUtil.getConfig("thread.max.pool.size");
int corePoolSize = 0;
int maxPoolSize = 0;
if ((corePoolSizeStr != null) && (!corePoolSizeStr.equals(""))) {
corePoolSize = Integer.valueOf(corePoolSizeStr);
}
if ((maxPoolSizeStr != null) && (!maxPoolSizeStr.equals(""))) {
maxPoolSize = Integer.valueOf(maxPoolSizeStr);
}
if ((corePoolSize == 0) || (maxPoolSize == 0)) {
LOGGER.log(Level.INFO, "Use default thread pool configuration.");
return;
}
if ((corePoolSize > maxPoolSize)) {
LOGGER.log(Level.SEVERE, "Core pool size greater than max pool sixe in configuration.");
LOGGER.log(Level.INFO, "Use default thread pool configuration.");
return;
}
//参考http://jersey.576304.n2.nabble.com/It-s-very-hard-to-increase-the-number-of-worker-threads-in-Jersey-Grizzly-module-td7579570.html
NetworkListener nl = server.getListener("grizzly");
System.out.println(nl.toString());
TCPNIOTransport transport = nl.getTransport();
ThreadPoolConfig config = transport.getWorkerThreadPoolConfig();
config.setCorePoolSize(corePoolSize);
String info = "Set thread core pool size [" + corePoolSize + "].";
LOGGER.log(Level.INFO, info);
config.setMaxPoolSize(maxPoolSize);
info = "Set thread max pool size [" + maxPoolSize + "].";
LOGGER.log(Level.INFO, info);
GrizzlyExecutorService threadPool = (GrizzlyExecutorService) transport.getWorkerThreadPool();
threadPool.reconfigure(config);
}
/**
* RestfulServer method.
*
* @param args
*/
public static void main(String[] args) {
startServer();
if (server.isStarted()) {
LOGGER.log(Level.INFO, "Start http server sucessfully.");
} else {
LOGGER.log(Level.SEVERE, "Start http server failed.");
}
}
}
微服务入口Action接口
package com.robin.loader;
/**
* <DT><B>描述:</B></DT>
* <DD>微服务入口Action接口</DD>
*
* @version Version1.0
* @author Robin
* @version <I> V1.0 Date:2018-05-04</I>
* @author <I> E-mail:xsd-jj@163.com</I>
*/
public interface MircoServiceAction {
public Object action(Object obj);
}
知更鸟博文推荐 | |
---|---|
上一篇 | 基于Kubernetes、Docker的机器学习微服务系统设计系列——(二)架构与部署 |
下一篇 | 基于Kubernetes、Docker的机器学习微服务系统设计系列——(四)中文分词微服务 |
推荐篇 | 基于Kubernetes、Docker的机器学习微服务系统设计——完整版 |
研究篇 | RS中文分词 | MP特征选择 | NLV文本分类 | 快速kNN |
作者简介 | |
兴趣爱好 | 机器学习、云计算、自然语言处理、文本分类、深度学习 |
xsd-jj@163.com (欢迎交流) |