《利用Java框架实现Restful接口》

1.生产场景


生产场景中,有一个php后台程序负责采集用户访问门户的数据,之前采用的是piwik+mysql的采集存储架构,后来投产后,发现每天数据量将近30万条之多!!!显然,原生的mysql是跑不动了。而kafka又不提供php接口,所以将采集存储方案转换为了restful接口的方案。


2.需求


php采集程序,通过post请求将json数据格式发至该restful接口,负责提供该接口的程序,接收到该post请求后,解析该json数据,通过协商好的各字段值,和Hbase交互,执行该数据的增改删操作,并将该数据操作的结果封装成json返回给php采集程序。


3.基本常识


java异常信息保存的一个简单方法

Web Serveice百度百科

四种常见的 POST 提交数据方式

将数据封装为Json数据格式

json-lib....jar 架包 jsonObject介绍

java 各种类型数据,集合对象封装 成json

关于Json的jar包有很多,Php采集程序post的json数据被转换为JSONObject格式,但经测试发现,如果导入的是org.json.JSONObject jar包是无法成功接收到的,需改用net.sf.json.JSONObject。前者与后者在JSONObject化的方法上还是有区别的。比如我有如下json类型的数据:

data={"id":1,"content":"Hello, World!"}

org.json.JSONObject将之转换为JSONObject,是通过如下方式:

JSONObject dataObj=new JSONObject(data),此时dataObj即为data转换后的JSONObject格式。

但是net.sf.json.JSONObject用之即会报错,它实现的方式如下:

JSONObject dataObj = JSONObject.fromObject(data);

需要注意一下。


4.环境部署

WIN7系统JavaEE(java+tomcat7+Eclipse)环境配置

Linux下安装Tomcat服务器和部署Web应用

修改tomcat端口号

修改tomcat默认的编码方式

手把手图文教你eclipse下如何配置tomcat

windows cmd窗口下tomcat关闭和重启的命令是什么?

搭建一个RESTFUL风格的Web Service (Maven版本)

eclipse构建及运行maven web项目

eclipse 创建maven 项目 动态web工程完整示例 

Eclipse+Maven创建webapp项目

如何用Maven创建web项目(具体步骤)

按照上述文档,可能由于Maven版本等问题,可能会出现步骤展现不一致现象,试着通过如下三篇文章解决:

(转)利用Eclipse创建maven项目并生成META-INF和WEB-INF目录

web.xml is missing and is set to true[解决]

maven项目转web项目时Java Build path entrles里没有内容



5.设计方案


①Jersey框架

用Jersey开发RESTful服务

com.sun.jersey.api.container.ContainerException

Web编程学习四: 使用Jersey来创建RESTful WebService


②Spring框架

Spring3 MVC 注解(一)---注解基本配置及@controller和 @RequestMapping 常用解释

使用Spring框架实现RESTful

SpringMVC写REST接口:第二篇 配置Maven的pom.xml文件


③Java与Hbase交互

Hbase常用操作(增删改查)

JAVA连接HBase

	public HBaseCommonUtil(String rootDir,String zooKeeperAddress,String clientPort) {
		HBASE_CONFIG = new Configuration();
		HBASE_CONFIG.set("hbase.rootdir", rootDir);
		HBASE_CONFIG.set("hbase.zookeeper.quorum", zooKeeperAddress);
		HBASE_CONFIG.set("hbase.zookeeper.property.clientPort", clientPort);
		conf = HBaseConfiguration.create(HBASE_CONFIG);
		try {
			conn = ConnectionFactory.createConnection(conf);
			hbaseAdmin = (HBaseAdmin) conn.getAdmin();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}


新增操作

	//Hbase新增操作
	public void insertData(String tableName,String rowKey,String column,String value) {
		try {
			HTable table = new HTable(conf, tableName);
			Put put = new Put(Bytes.toBytes(rowKey));
			put.add(Bytes.toBytes("detail"), Bytes.toBytes(column), Bytes.toBytes(value));
			table.put(put);
			table.close();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

删除操作

	
	//Hbase删除操作
	public void deleteData(String tableName, String rowKey) throws IOException {
		HTable table;
		table = new HTable(conf, tableName);
		List list = new ArrayList();
		Delete del = new Delete(rowKey.getBytes());
		list.add(del);
		table.delete(list);
		table.close();
	}


更新操作

	//Hbase更新操作
	public void updateData(String tableName, String rowKey, String column, String value) throws IOException {
		HTable table = new HTable(conf, tableName);
		Put p = new Put(Bytes.toBytes(rowKey));
		p.add(Bytes.toBytes("detail"), Bytes.toBytes(column), Bytes.toBytes(value));
		table.put(p);
		table.close();
	}

6.性能优化

初步设计方案在测试中发现“Got ping response for sessionid”,远程主机强制关闭一个连接以及您本机中的软件关掉一个连接,这样的错误。百思不得其解,后来小伙伴看了下之前的代码,找到了错误的源头:

①每提交一次,就会执行一次Controller方法,而连接Hbase的操作放在这个方法中,所以每次都会连接一次。

②而Hbase在通过java进行交互的时候,需要知道待操作的数据的表名,通过HTable table = new HTable(conf,tableName)。这个可以通过放在一个map中,来避免每次的new的耗时;

具体操作为,定义一个Map:Map<String,HTable> tableMap,在构造方法中初始化这个Map,执行到与Hbase交互时,首先判断tableMap.get(tableName)是否可以取到相应的HTable初始化方法,可以即直接从Map中get到这个初始化,不可以说明是第一次,需将tableName和初始化方式添加给这个Map。具体代码如下:

<span style="font-family:Microsoft YaHei;font-size:14px;">if(tableMap.get(tableName)==null)
{
tableMap.put(tableName,new HTable(util.getConf,tableName));
}
HTable table = tableMap.get(tableName);</span>


③同时之前有一个误区,就是在操作Hbase的时候,Hbase不能批量进行插入,以为每次在put的时候,只能一个value,所以将put操作放到了循环中,改良后的操作方式为将每次提交的数据中的value一次性添加到put中,一次性提交这个put。

做到以上三点,基本上就没出现过上述错误,并且一万条数据耗时100秒,而生产场景的巅峰值是一秒60几条,绰绰有余。


7.常见问题


eclipse (kepler) 创建 maven 项目 添加src/main/java出问题

maven 加入json-lib.jar 报错 Missing artifact net.sf.json-lib:json-lib:jar:2.4:compile

解决maven引用jdk中的tools.jar报Missing artifact的问题

The processing instruction target matching "[xX][mM][lL]" is not allowed怎么办?

eclipse导出jar包export-->runnable jar file的launch configuration里的内容不更新解决

经过web.xml加载spring容器时遇到java.lang.ClassNotFoundException: org.springframework.web

(如若不行试着删除WebApp lib目录下的com.google.*jar包)






你可能感兴趣的:(java,Web,springMVC,hbase,Restful)