0%

密码错误重试导致数据库超慢

有同事把项目的数据库密码配错了,导致其他所有连接该数据库的项目全部连接都获取缓慢了,一个页面加载要花费十几秒。排查mysql连接发现很多connect命令的连接

1
show full PROCESSLIST

由于连接的host全是我们服务器的ip,所以一开始想到的是服务器是不是被黑了,然后频繁的尝试破解数据库密码

赶紧查了一下是哪个进程在连接数据库

1
netstat -anp | grep 3306

结果发现pid是我们自己的项目,拉下来代码一看,密码配置的不对

阅读全文 »

HBase协处理器

协处理器允许用户在region服务器上运行自己的代码,实现了相当于触发器的功能。如可以使用协处理器在进行hbase操作时将数据同步到es

协处理器提供了两类协处理器observer和endpoint

  • observer 这一类协处理器与触发器类似,在一些特定事件发生时被执行。包含接口如下
    • RegionObserver 可以使用这种处理器处理数据修改事件,与表的region联系紧密
    • MasterObserver 可以用作管理或DDL类型的操作,属于集群级事件
    • WALObserver 提供控制WAL的钩子函数
  • endpoint 通过添加一些远程过程调用来动态扩展RPC协议,可以理解为类似于存储过程

小示例

阅读全文 »

HBase客户端API

简单一点,先假定只操作table表,创建table对象

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// 使用Admin对象来操作DDL
private static Admin admin;
// 使用Table对象来操作DML
private static Table table;

static {
try {
// 获取连接
Connection conn = ConnectionFactory.createConnection();
admin = conn.getAdmin();
table = conn.getTable(TableName.valueOf("test"));
} catch (IOException e) {
e.printStackTrace();
}
}

插入数据

先插入一条数据,来方便后续的查找操作

1
2
3
4
5
6
7

public static void testPut(String rowKey,String family,String q,String value) throws IOException {
Put put = new Put(Bytes.toBytes(rowKey));

put.addColumn(Bytes.toBytes(family),Bytes.toBytes(q),Bytes.toBytes(value));
table.put(put);
}
阅读全文 »

EasyExcel合并单元格

写excel不可避免的会使用到合并单元格,之前也说过EasyExcel提供了对于excel文件、sheet页、行以及单元格的钩子,合并单元格用到的就是单元格的钩子,也就是实现CellWriteHandler接口。

而且EasyExcel提供了一个合并单元格的抽象类AbstractMergeStrategy,可以继承该类来实现merge方法。

这里简单实现了一个自定义的合并单元格,与该列的上一行比较值是否相同,相同的话就进行合并

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
static class CustomMergeCellHandler extends AbstractMergeStrategy {

// 需要合并的字段
private List<String> mergeFields;
// 总条数
private int count;
public CustomMergeCellHandler(List<String> mergeFields,int count){
this.mergeFields = mergeFields;
this.count = count;
}

// 存储上次的值 Pair left为值,right为上次出现为第几行
private Map<String, Pair<Object,Integer>> previousValueMap = new HashMap<>();

@Override
protected void merge(Sheet sheet, Cell cell, Head head, Integer relativeRowIndex) {

int curRowNum = relativeRowIndex+1;
if(mergeFields != null && mergeFields.size() > 0){
if(mergeFields.contains(head.getFieldName())){ // 是否是需要合并的字段
if(previousValueMap.containsKey(head.getFieldName())){
// 比较是否相等
Pair<Object, Integer> pair = previousValueMap.get(head.getFieldName());
Object curValue = getCellValue(cell);

if(!pair.getLeft().equals(curValue)){ // 不相等,需要进行合并处理
if(curRowNum - pair.getRight() > 1){ // 只有一行时不进行处理
sheet.addMergedRegion(new CellRangeAddress(pair.getRight(), curRowNum - 1, cell.getColumnIndex(), cell.getColumnIndex()));

}
// 置为最新的值
previousValueMap.put(head.getFieldName(),Pair.of(curValue,curRowNum));
} else { // 如果是最后一行,也要进行合并
if(count == curRowNum){
if(curRowNum - pair.getRight() > 1){ // 只有一行时不进行处理
sheet.addMergedRegion(new CellRangeAddress(pair.getRight(), curRowNum, cell.getColumnIndex(), cell.getColumnIndex()));

// 置为最新的值
previousValueMap.put(head.getFieldName(),Pair.of(curValue,curRowNum));
}
}

}

} else {
Object curValue = getCellValue(cell);
previousValueMap.put(head.getFieldName(),Pair.of(curValue,curRowNum));
}
}
}
}

protected Object getCellValue(Cell cell) {
if (Objects.isNull(cell)) {
return "";
}

CellType cellTypeEnum = cell.getCellTypeEnum();
switch (cellTypeEnum) {
case STRING:
return cell.getStringCellValue();
case BOOLEAN:
return cell.getBooleanCellValue();
case NUMERIC:
return cell.getNumericCellValue();
default:
return "";
}
}
}
阅读全文 »

EasyExcel钩子

EasyExcel中提供了几个接口来进行钩子操作

workbook钩子

workbook创建前后的钩子方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
public interface WorkbookWriteHandler extends WriteHandler {

/**
* Called before create the workbook
*
* @param context
*/
default void beforeWorkbookCreate(WorkbookWriteHandlerContext context) {
beforeWorkbookCreate();
}

/**
* Called before create the workbook
*/
default void beforeWorkbookCreate() {}

/**
* Called after the workbook is created
*
* @param context
*/
default void afterWorkbookCreate(WorkbookWriteHandlerContext context) {
afterWorkbookCreate(context.getWriteWorkbookHolder());
}

/**
* Called after the workbook is created
*
* @param writeWorkbookHolder
*/
default void afterWorkbookCreate(WriteWorkbookHolder writeWorkbookHolder) {}

/**
* Called after all operations on the workbook have been completed
*
* @param context
*/
default void afterWorkbookDispose(WorkbookWriteHandlerContext context) {
afterWorkbookDispose(context.getWriteWorkbookHolder());
}

/**
* Called after all operations on the workbook have been completed
*
* @param writeWorkbookHolder
*/
default void afterWorkbookDispose(WriteWorkbookHolder writeWorkbookHolder) {}
}
阅读全文 »