java实现服务端守护进程来监听客户端通过上传json文件写数据到hbase中
1、项目介绍:
由于大数据部门涉及到其他部门将数据传到数据中心,大部分公司采用的方式是用json文件的方式传输,因此就需要编写服务端和客户端的小程序了。而我主要实现服务端的代码,也有相应的客户端的测试代码。这里须有一个需要提到的是,我在实现接收json文件的同时,而且还需将数据写到hbase中。写入到hbase当中采用的是批量插入的方式,即一次插入多条记录。
好了,有了前面的说明,下面来简单的说一下我实现的服务端的小程序把。
2、为了实现服务端能够监听客户端的行为,因此我在服务端采用多线程的技术来实现,并用socket的方式来实现网络通信。具体实现如下:
服务端的主程序:
package com.yiban.datacenter.finalversion; import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket; public class HbaseServer { public static void main(String[] args) {
// TODO Auto-generated method stub
backprocess();
} public static void backprocess(){
try {
ServerSocket ss=new ServerSocket(11111);
while(true){
Socket s=ss.accept(); Thread deal=new Thread(new DealUserThread(s));
deal.setDaemon(true); //这里设置对应线程是后台线程
deal.start();
} } catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
处理数据的线程类:
在这里我实现了接收数据,并将数据写入hbase中。
在实现这些大的目标的同时,也将客户端的请求通过日志文件的形式存到服务端的本地磁盘上,供后续查看。
package com.yiban.datacenter.finalversion; import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.Socket;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.TreeMap; import net.sf.json.JSONArray;
import net.sf.json.JSONObject; import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.hbase.HBaseConfiguration;
import org.apache.hadoop.hbase.HColumnDescriptor;
import org.apache.hadoop.hbase.HConstants;
import org.apache.hadoop.hbase.HTableDescriptor;
import org.apache.hadoop.hbase.MasterNotRunningException;
import org.apache.hadoop.hbase.TableName;
import org.apache.hadoop.hbase.ZooKeeperConnectionException;
import org.apache.hadoop.hbase.client.Admin;
import org.apache.hadoop.hbase.client.Connection;
import org.apache.hadoop.hbase.client.ConnectionFactory;
import org.apache.hadoop.hbase.client.HBaseAdmin;
import org.apache.hadoop.hbase.client.HTable;
import org.apache.hadoop.hbase.client.Put;
import org.apache.hadoop.hbase.client.Table;
import org.apache.hadoop.hbase.util.Bytes; public class DealUserThread implements Runnable { private String testconnect = "username=chenpiao,password=123;username=liujiyu,password=123"; // 这个可以用来验证用户名和密码 private static Configuration conf = HBaseConfiguration.create(); private static Connection connection = null; private String logFile=null;
// 配置hbase的信息
static {
try {
conf.set(HConstants.ZOOKEEPER_QUORUM, "192.168.27.233");
conf.setInt(HConstants.ZOOKEEPER_CLIENT_PORT, 2181);
connection = ConnectionFactory.createConnection(conf);
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
} private Socket s; public DealUserThread(Socket s) {
this.s = s;
} private String userTableName = "nihao";
private String columnFamilyName = null;
private String rowKey = null; private BufferedReader serverread = null;
private BufferedWriter serverwrite = null; @Override
public void run() {
// TODO Auto-generated method stub
try {
// 将通道内的字节流转换成字符流,并用bufferedreader进行封装,InputStreamReader是将字节流转换成字符流
serverread = new BufferedReader(new InputStreamReader(
s.getInputStream())); // 询问客户端连接是否准备好,接受客户端的连接请求
String line = serverread.readLine(); // 阻塞
//System.out.println(line);// 输出客户端的连接请求 //为日志文件命名,并创建文件
SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
logFile="/var/log/datacenter/"+"user.log";
//System.out.println(logFile);
File destFile = new File(logFile);
if (!destFile.exists()) {
destFile.createNewFile();
}
writeByFileWrite(logFile, line+"\n"+sdf.format(System.currentTimeMillis()));
// 将通道内的字符写入到对应的文件中,利用bufferedwrite进行封装,FileWriter是将字符流写入到文件中
serverwrite = new BufferedWriter(new OutputStreamWriter(
s.getOutputStream()));
String[] strArray = testconnect.split("\\;");
boolean flag = false;
for (String str : strArray) {
if (str.equals(line)) {
/*
* serverwrite.write("连接成功,你可以发送数据了,发送数据前,请先发送你要用的数据库表名!");
* serverwrite.newLine(); serverwrite.flush();
*/
printInfomationForClient("connection successful ,now you can send data,befor send data ,you must send tablename!");
flag = true;
break;
}
} if (!flag) {
/*
* serverwrite.write("密码或者用户名错误,连接失败!"); serverwrite.newLine();
* serverwrite.flush();
*/
printInfomationForClient("username or password is error! connection failed!");
s.close();
} // 准备接收表名
userTableName = serverread.readLine();
//System.out.println("tablename:" + userTableName);// 输出客户端的连接请求的表名 writeByFileWrite(logFile, "tablename="+userTableName);//将内容写到日志文件中 // 告诉客户端,我接受成功
if (TableIsExist(userTableName)) {
printInfomationForClient("received tablename successful!");
} else {
printInfomationForClient("tablename Is not exist ");
s.close();
} line = "[";
StringBuffer temp = new StringBuffer(line);
while ((line = serverread.readLine()) != null) {
temp.append(line);
}
temp.append("]");
//System.out.println(temp.toString()); // 对接收到的数据进行异常处理,如上传的数据格式不正确等等。
try {
// 对json文件进行解析
JSONArray jsonArray = JSONArray.fromObject(temp.toString());
// JSONObject jsonobject=JSONObject.fromObject(temp.toString()); // 解析之后进行输出
//PrintJsonArray(jsonArray); //获取所有的表名
//getAllTables(conf); // 将接收到的数据写入hbase中的表中
insertData(jsonArray, userTableName); //System.out.println("存入数据成功!"); } catch (Exception e) {
printErrorForClient(e);
}
// 给出一个反馈,提示数据上传成功
// 封装通道内的输出流,方便对他进行写字符数据
// BufferedWriter bwserver = new BufferedWriter(new
// OutputStreamWriter(s.getOutputStream())); /*
* serverwrite.write("文件上传成功!"); // bwserver.newLine();
* serverwrite.flush(); serverwrite.close();
*/
printInfomationForClient("upload data successful!"); // 释放资源
s.close(); } catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
try {
printErrorForClient(e);
writeByFileWrite(logFile,e.getMessage()+e.toString());
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
} private void printInfomationForClient(String s) throws IOException {
try {
serverwrite.write(s);
writeByFileWrite(logFile, s);//将内容写到日志文件中
serverwrite.newLine();
serverwrite.flush();
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
writeByFileWrite(logFile, e.getMessage()+e.toString());//将内容写到日志文件中
}
} private void printErrorForClient(Exception e) throws IOException {
try {
serverwrite.write("found a error:" + e.getMessage() + e.toString());
writeByFileWrite(logFile,"found a error:" + e.getMessage() + e.toString());
serverwrite.newLine();
serverwrite.flush();
s.close();
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
writeByFileWrite(logFile,e1.getMessage()+e1.toString());
} } Map<String, String> colvalue = new TreeMap<String, String>(); private void insertData(JSONArray jsonArray, String userTableName)
throws IOException { // connect the table
Table table = null;
try {
table = connection.getTable(TableName.valueOf(userTableName));
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
printErrorForClient(e1);
} colvalue.clear(); for (int i = 0; i < jsonArray.size(); i++) {
JSONObject obj = jsonArray.getJSONObject(i);
Set<String> keysets = obj.keySet();
for (String key : keysets) {
switch (key) {
case "category":
columnFamilyName = obj.getString(key);
break;
case "version":
colvalue.put("version", obj.getString("version"));
break;
case "DocumentType":
colvalue.put("DocumentType", obj.getString("DocumentType"));
break;
case "articles":
JSONArray articlesjars = obj.getJSONArray("articles");
dealjsonArray(table,articlesjars);
break;
default:
printErrorForClient(new Exception("send datatype is error!"));
}
} }
} private void insertColDataToHbase(Table table) throws IOException {
// 判断是否包含对应的列族,若不包含则添加
HTableDescriptor desc = new HTableDescriptor(table.getName());
Collection<HColumnDescriptor> familys=desc.getFamilies();
if ( familys.contains(new HColumnDescriptor(columnFamilyName))
&& columnFamilyName != null) {
addColFamily(table, desc, columnFamilyName);
} // insert data
List<Put> putlist = new ArrayList<Put>(); if (!colvalue.isEmpty() && rowKey != null && columnFamilyName != null) {
Put put = new Put(Bytes.toBytes(rowKey));// 指定行,也就是键值
// 下面就是循环存储列
for (Entry<String, String> col : colvalue.entrySet()) {
put.add(Bytes.toBytes(columnFamilyName),
Bytes.toBytes(col.getKey()),
Bytes.toBytes(col.getValue()));
putlist.add(put);
} } else {
printErrorForClient(new Exception("send datatype is error!"));
} try {
table.put(putlist);
table.close();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
printErrorForClient(e);
}
} private void dealjsonArray(Table table,JSONArray articlesjars) throws IOException {
// TODO Auto-generated method stub
if(articlesjars.isEmpty()){
System.out.println("articlesjars is empty");
printErrorForClient(new Exception("send datatype is error!"));
return;
}
for(int i=0;i<articlesjars.size();i++){
JSONObject obj=articlesjars.getJSONObject(i);
Set<String>keysets=obj.keySet();
for(String key:keysets){
switch(key){
case "content":
colvalue.put("content", obj.getString("content"));
break;
case "picture_url":
colvalue.put("picture_url", obj.getString("picture_url"));
break;
case "time":
colvalue.put("time", obj.getString("time"));
break;
case "author":
colvalue.put("author", obj.getString("author"));
break;
case "url":
rowKey=obj.getString("url");
break;
case "title":
colvalue.put("title", obj.getString("title"));
break;
default:
printErrorForClient(new Exception("send datatype is error!"));
}
}
try {
insertColDataToHbase(table);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
printErrorForClient(e);
}
} } private void addColFamily(Table table, HTableDescriptor desc,
String colFamily) throws IOException { Admin ad = connection.getAdmin(); HColumnDescriptor family = new HColumnDescriptor(
Bytes.toBytes(colFamily));// 列簇
desc.addFamily(family);
ad.addColumn(table.getName(), family);
ad.close(); } private boolean TableIsExist(String userTableName2) throws IOException {
boolean flag = false;
try {
// Connection connection = ConnectionFactory.createConnection(conf);
Admin ad = connection.getAdmin();
if (ad.tableExists(TableName.valueOf(userTableName2))) {
flag = true;
//System.out.println("表存在");
} else {
//System.out.println("表不存在");
//printErrorForClient(new Exception("表不存在"));
}
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
printErrorForClient(e);
} return flag;
// TODO Auto-generated method stub } private void PrintJsonArray(JSONArray jsonArray) {
int size = jsonArray.size();
System.out.println("Size: " + size);
for (int i = 0; i < size; i++) {
JSONObject jsonObject = jsonArray.getJSONObject(i);
Set<String> keysets = jsonObject.keySet();
for (String keyset : keysets) {
System.out.println(keyset);
}
}
} private void PrintJsonArray(JSONObject jsonobject, String... keys) {
int size = jsonobject.size();
System.out.println("Size: " + size);
for (int i = 0; i < size; i++) {
for (String key : keys) {
System.out.println(key + ":" + jsonobject.get(key));
} // System.out.println("[" + i + "]id=" + jsonObject.get("id"));
// System.out.println("[" + i + "]name=" + jsonObject.get("name"));
// System.out.println("[" + i + "]role=" + jsonObject.get("role"));
}
} //写日志文件
public static void writeByFileWrite(String _sDestFile, String _sContent)
throws IOException {
FileWriter fw = null;
try {
fw = new FileWriter(_sDestFile,true);
fw.write(_sContent);
fw.write('\n');
} catch (Exception ex) {
ex.printStackTrace();
} finally {
if (fw != null) {
fw.close();
fw = null;
}
}
} // create table
private void createTable(Configuration conf) {
// HBaseAdmin ha=new HBaseAdmin(conf);
try {
// Connection connection = ConnectionFactory.createConnection(conf);
Table table = connection.getTable(TableName.valueOf(userTableName));
Admin ad = connection.getAdmin(); // TableName name= TableName.valueOf(Bytes.toBytes(tablename));//表名
HTableDescriptor desc = new HTableDescriptor(table.getName()); HColumnDescriptor family = new HColumnDescriptor(
Bytes.toBytes(columnFamilyName));// 列簇
desc.addFamily(family); ad.createTable(desc);
ad.close(); } catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
} } // Hbase获取所有的表信息
public static List getAllTables(Configuration conf)
throws MasterNotRunningException, ZooKeeperConnectionException,
IOException { HBaseAdmin ad = new HBaseAdmin(conf);
List<String> tables = null;
if (ad != null) {
try {
HTableDescriptor[] allTable = ad.listTables();
if (allTable.length > 0)
tables = new ArrayList<String>();
for (HTableDescriptor hTableDescriptor : allTable) {
tables.add(hTableDescriptor.getNameAsString());
System.out.println(hTableDescriptor.getNameAsString());
}
} catch (IOException e) {
e.printStackTrace();
}
}
return tables;
} }
实现了这些之后,通过eclipse将其导出程可运行的jar包,并将jar包放到服务器上进行部署,部署的方式很简单,但是也要注意一下:
java -jar myserver.jar com.yiban.datacenter.finalversion.HbaseServer &
最后一个&表示后台守护启动该进程。
java实现服务端守护进程来监听客户端通过上传json文件写数据到hbase中的更多相关文章
- 通过FileWatcher,监听通过web上传的图片,并进行压缩
需求是这样的,通过web传输过来的图片,无论是JS上传,还是其他的上传方式,都需要生成2张缩略图,分别是用于商品列表的小图small,和用于分享的小图share.基于不同上传方式的不同需求,使用exe ...
- Linux控制服务和守护进程
目录 控制服务和守护进程 1.systemd 1.1.systemd简介 1.2.systemd的新特性 1.3.systemd的核心概念Unit 2.使用systemctl管理服务 控制服务和守护进 ...
- NIO【同步非阻塞io模型】关于 NIO socket 的详细总结【Java客户端+Java服务端 + 业务层】【可以客户端间发消息】
1.前言 以前使用 websocket来实现双向通信,如今深入了解了 NIO 同步非阻塞io模型 , 优势是 处理效率很高,吞吐量巨大,能很快处理大文件,不仅可以 做 文件io操作, 还可以做sock ...
- Unity手游之路<二>Java版服务端使用protostuff简化protobuf开发
http://blog.csdn.net/janeky/article/details/17151465 开发一款网络游戏,首先要考虑的是客户端服务端之间用何种编码格式进行通信.之前我们介绍了Unit ...
- Java Socket 服务端发送数据 客户端接收数据
服务端: package com.thinkgem.wlw.modules.api.test.socket; /** * @Author: zhouhe * @Date: 2019/4/8 9:30 ...
- Supervisor 为服务创建守护进程
今天需要再服务上部署一个.net 方面的项目:当时开启服务的命令只能在前台执行:使用nohub CMD &等放在后台开启服务都会宕机:所以搜寻了Supervisor 这个解决办法,为服务创建守 ...
- java实现服务端开启多线程处理客户端的上传图片请求
将客户端c:\\a.jpg 上传到e:\\公司名称+6位随机数.jpg 这样为了不断开连接客户端每次上传的图片名字不重名覆盖,验证之用 这里需要注意的是Socket的终止客户端的输入方法 shut ...
- 七牛云java(服务端)通用工具类
前言 需要安装lombok插件. 功能列表 上传本地文件 上传Base64图片 获取文件访问地址 上传MultipartFile 代码 pom.xml <dependency> <g ...
- [Java聊天室server]实战之二 监听类
前言 学习不论什么一个稍有难度的技术,要对其有充分理性的分析,之后果断做出决定---->也就是人们常说的"多谋善断":本系列尽管涉及的是socket相关的知识,但学习之前,更 ...
随机推荐
- Solr Cloud - SolrCloud
关于 Solr Cloud Zookeeper 入门,介绍 原理 原封不动转自 http://wiki.apache.org/solr/SolrCloud/ ,文章的内存有些过时,但是了解原理. Th ...
- 使用requestAnimationFrame做动画效果一
最近学习了requestAnimationFrame,看了张鑫旭直白易懂,但是某些地方语言过于裸露的文章http://www.zhangxinxu.com/wordpress/2013/09/css3 ...
- python+selenium安装步骤
1.先安装python 2.下载setuptools 使用方法是在 命令提示符(cmd)下 输入 "easy_install包名称" 3.安装pip 4.安装selenium如果是 ...
- JavaScript高阶函数 map reduce filter sort
本文是笔者在看廖雪峰老师JavaScript教程时的个人总结 高阶函数 一个函数就接收另一个函数作为参数,这种函数就称之为高阶函数 1.高阶函数之map: ...
- Unity3D 中的定时器
不算上 C# 自带的,目前知道两种,以下分别介绍. 1.每帧检查 定义一个时间变量 timer,每帧将此时间减去帧间隔时间 Time.deltaTime,如果小于或者等于零,说明定时器到了,执行相应功 ...
- php 面试题收集-基础题
1.表单中 get与post提交方法的区别?答:get是发送请求HTTP协议通过url参数传递进行接收,而post是实体数据,可以通过表单提交大量信息. 2.session与cookie的区别?答:s ...
- vue.common.js?e881:433 TypeError: Cannot read property 'nodeName' of undefined
我觉得吧,是这么个原因,就是响应式要找这个node改它的内容,没找着,就报错了. 用computed监控vuex的state属性,绑定到页面上,如果这个属性改了,因为响应式,那么就要更改页面,如果页面 ...
- Redis常用命令入门4:集合类型
集合类型 之前我们已经介绍过了最基本的字符串类型.散列类型.列表类型,下面我们一起学习一下集合类型. 集合类型也是体现redis一个比较高价值的一个类型了.因为Redis的集合类型,所以我们可以很容易 ...
- jquery触屏幻灯片
一.前言 去年接触了移动Web开发,做了些手机端的网站及应用,还有些小的微信游戏和活动页面.每个项目里或多或少的都会有一些触屏事件等.其中有两个用到了jquery触屏幻灯片.刚开始的时候也在百度上搜索 ...
- 第一个C语言程序
从第一个C语言程序了解C语言 了解关键字 了解函数 注释 C语言的执行流程 标识符 C语言的学习重难点 从第一个C语言程序了解C语言 上图是一个在控制台上显示“Hello, World!”的C语言源代 ...