利用Java框架实现Restful接口

1.生产场景

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

2.需求

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

3.基本常识

  1. Java异常信息保存的一个简单方法
  2. Web Serveice百度百科
  3. 四种常见的 POST 提交数据方式
  4. 将数据封装为Json数据格式
  5. json-lib....jar 架包 jsonObject介绍
  6. 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.环境部署

  1. WIN7系统JavaEE(java+tomcat7+Eclipse)环境配置
  2. 修改tomcat默认的编码方式
  3. Linux下安装Tomcat服务器和部署Web应用
  4. 修改tomcat端口号
  5. 手把手图文教你eclipse下如何配置tomcat
  6. windows cmd窗口下tomcat关闭和重启的命令是什么?
  7. 搭建一个RESTFUL风格的Web Service (Maven版本)
  8. eclipse构建及运行maven web项目
  9. eclipse 创建maven 项目 动态web工程完整示例
  10. Eclipse+Maven创建webapp项目
  11. 如何用Maven创建web项目(具体步骤)
    按照上述文档,可能由于Maven版本等问题,可能会出现步骤展现不一致现象,试着通过如下三篇文章解决
  12. (转)利用Eclipse创建maven项目并生成META-INF和WEB-INF目录
  13. web.xml is missing and is set to true[解决]
  14. 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 tableMap,在构造方法中初始化这个Map,执行到与Hbase交互时,首先判断tableMap.get(tableName)是否可以取到相应的HTable初始化方法,可以即直接从Map中get到这个初始化,不可以说明是第一次,需将tableName和初始化方式添加给这个Map。具体代码如下:

if(tableMap.get(tableName)==null)
{
    tableMap.put(tableName,
    new HTable(util.getConf,tableName));
}
HTable table = tableMap.get(tableName);

③同时之前有一个误区,就是在操作Hbase的时候,Hbase不能批量进行插入,以为每次在put的时候,只能一个value,所以将put操作放到了循环中,改良后的操作方式为将每次提交的数据中的value一次性添加到put中,一次性提交这个put。
做到以上三点,基本上就没出现过上述错误,并且一万条数据耗时100秒,而生产场景的巅峰值是一秒60几条,绰绰有余。

7.常见问题

  1. eclipse (kepler) 创建 maven 项目 添加src/main/java出问题
  2. maven 加入json-lib.jar 报错 Missing artifact net.sf.json-lib:json-lib:jar:2.4:compile
  3. 解决maven引用jdk中的tools.jar报Missing artifact的问题
  4. The processing instruction target matching "[xX][mM][lL]" is not allowed怎么办?
  5. eclipse导出jar包export-->runnable jar file的launch configuration里的内容不更新解决
  6. 经过web.xml加载spring容器时遇到java.lang.ClassNotFoundException: org.springframework.web
    (如若不行试着删除WebApp lib目录下的com.google.jar包)*

你可能感兴趣的:(利用Java框架实现Restful接口)