生产场景中,有一个php后台程序负责采集用户访问门户的数据,之前采用的是piwik+mysql的采集存储架构,后来投产后,发现每天数据量将近30万条之多!!!显然,原生的mysql是跑不动了。而kafka又不提供php接口,所以将采集存储方案转换为了restful接口的方案。
php采集程序,通过post请求将json数据格式发至该restful接口,负责提供该接口的程序,接收到该post请求后,解析该json数据,通过协商好的各字段值,和Hbase交互,执行该数据的增改删操作,并将该数据操作的结果封装成json返回给php采集程序。
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);
需要注意一下。
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里没有内容
用Jersey开发RESTful服务
com.sun.jersey.api.container.ContainerException
Web编程学习四: 使用Jersey来创建RESTful WebService
Spring3 MVC 注解(一)---注解基本配置及@controller和 @RequestMapping 常用解释
使用Spring框架实现RESTful
SpringMVC写REST接口:第二篇 配置Maven的pom.xml文件
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(); }
初步设计方案在测试中发现“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几条,绰绰有余。
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包)