服务器时间错误导致MySQL证书错误问题

HibernateException ‘hibernate.dialect’ not set


同一个jar包,在某个环境下启动应用报错,另一个环境可以正常启动。报上面的错误

1
caused by: org.hibernate.HibernateException: Access to DialectResolutionInfo cannot be null when 'hibernate.dialect' not set

MySQL证书错误

查看MySQL日志mysql/mysqld.log其中有

1
2
2000-02-05T02:19:10.762462Z 0 [Note] Found ca.pem, server-cert.pem and server-key.pem in data directory. Trying to enable SSL support using them.
2000-02-05T02:19:10.762482Z 0 [Note] Skipping generation of SSL certificates as certificate files are present in data directory.

MySQL cert error

Read More

选择横表还是纵表

数据库:MySQL 5.7
业务上有25个维度共2000多个指标数据需要存储。对于这种可变字段的指标数据,第一想法是采用纵表存储。但是具体该如何选择还是得结合业务看优缺点才行。

业务场景

数据量

1k台设备,每台设备每5分钟一次全量指标数据,存储60天

  • 纵表:602460/510002000=345.6亿
  • 横表:345.6亿/2000=1728万
查询场景
  • 按指标维度+时间范围分页查
  • 按同一时间上报的指标数据(时间+指标名称)

Read More

宽表、窄表、横表、纵表有什么不同

宽表、窄表是大数据中的概念

宽表,字段比较多的数据库表。将业务主题相关的多个维度的字段关联在一起的一张数据库表。
宽表的本质:以空间换时间
好处:

  • 统一口径
  • 降低统计难度,减少表之间的关联
  • 节省跑数时间
  • 节省资源

窄表,符合三范式,相同维度的字段组成一张表。表和表之间关联查询。

横表、纵表
横表:也称为行表,将数据按照行进行排列。
纵表:也称为列式表或属性表,将数据按照列进行排列。

Read More

如何找到导致fullgc的问题代码

服务频繁fullgc无法对外提供服务。需要查看分析出是大对象?内存分配不合理还是造成了内存泄漏的问题。
查找步骤

  • 查看,确认gc情况
  • 查看jvm运行参数

  • dump分析

  • 找出问题代码

  • 查看存活对象情况

  • 查看该进程下占用CPU最高的线程

查看,确认gc情况

1
jstat -gc [pid] 2000

每2秒打印一次pid的gc情况
jstat gc

Read More

牛仔裤中的牛仔是什么

Q

牛仔裤中的牛仔是什么

A

“牛仔裤”一词源自英文单词“jeans”,最早可以追溯到1567年意大利热那亚港水手穿的一种粗帆布制作的裤子,当时水手们喜欢穿着这种粗糙而结实的布料做成的工作裤子,称之为Genoese, Genes,与Jeans有着相似的发音。1850年淘金热的浪潮下,移民到美国的巴伐利亚人李维·斯特劳斯创立了李维斯公司,该公司生产的帆布工装裤就是世人所知的牛仔裤的鼻祖。这种布料结实耐磨,十分适合应付繁重的日常劳作,受到当时矿工们的喜欢。
因此,牛仔裤中的“牛仔”并不是指牛,而是指穿着这种裤子的工人和冒险家
jeans

XML元素名称规范

背景

使用dom4j生成XML,期望结果
生成XML数据

1
<gNB间NG切换成功率(%)>100</gNB间NG切换成功率(%)>

但是抛错
1
2
3
4
5
6
7
8
9
java.lang.IllegalArgumentException: Illegal character in name: 'gNB间NG切换成功率(%)'.

at org.dom4j.QName.validateName(QName.java:340)
at org.dom4j.QName.<init>(QName.java:151)
at org.dom4j.tree.QNameCache.createQName(QNameCache.java:245)
at org.dom4j.tree.QNameCache.get(QNameCache.java:115)
at org.dom4j.DocumentFactory.createQName(DocumentFactory.java:191)
at org.dom4j.tree.AbstractElement.addElement(AbstractElement.java:760)
at Dom4jTest.test_AddTagBySpecial(Dom4jTest.java:25)

Read More

ThreadPoolExecutor学习

  • 创建线程的几种方式
    • Thread
    • Runnable
    • Callable(配合Future获取返回值)
    • 线程池
      • Executors
      • ThreadPoolExecutor
  • 线程池ThreadPoolExcecutor的7个参数
    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
    /**
    * Creates a new {@code ThreadPoolExecutor} with the given initial
    * parameters.
    *
    * @param corePoolSize the number of threads to keep in the pool, even
    * if they are idle, unless {@code allowCoreThreadTimeOut} is set
    * @param maximumPoolSize the maximum number of threads to allow in the
    * pool
    * @param keepAliveTime when the number of threads is greater than
    * the core, this is the maximum time that excess idle threads
    * will wait for new tasks before terminating.
    * @param unit the time unit for the {@code keepAliveTime} argument
    * @param workQueue the queue to use for holding tasks before they are
    * executed. This queue will hold only the {@code Runnable}
    * tasks submitted by the {@code execute} method.
    * @param threadFactory the factory to use when the executor
    * creates a new thread
    * @param handler the handler to use when execution is blocked
    * because the thread bounds and queue capacities are reached
    * @throws IllegalArgumentException if one of the following holds:<br>
    * {@code corePoolSize < 0}<br>
    * {@code keepAliveTime < 0}<br>
    * {@code maximumPoolSize <= 0}<br>
    * {@code maximumPoolSize < corePoolSize}
    * @throws NullPointerException if {@code workQueue}
    * or {@code threadFactory} or {@code handler} is null
    */
    public ThreadPoolExecutor(int corePoolSize,
    int maximumPoolSize,
    long keepAliveTime,
    TimeUnit unit,
    BlockingQueue<Runnable> workQueue,
    ThreadFactory threadFactory,
    RejectedExecutionHandler handler)
    • corePoolSize(核心线程数)
    • maximumPoolSize(最大线程数)
    • keepAliveTime、unit(最大空闲时间)
    • workQueue(阻塞队列)
    • threadFactory(线程工厂,为线程自定义名称)
    • handler(拒绝策略)
  • 线程池执行流程

Read More

Facebook广告中使用Deferred Deep Link

在运营时,学习使用了App Link和Deep Link,之前也使用了Firebase中的Dynamic Links在用户未安装App时跳转至Google Play安装后再打开仍然能获取到链接内容,带用户到推荐的个性化页面。
后面由于运营需要在Facebook上做推广,需要接入Meta的Deep Link
运营时有3个场景,我们的App,以下简称A

  1. 用户已安装A,点击Facebook广告链接,正常打开A并跳转至推广页面
  2. 用户未安装A,点击Facebook广告链接,打开Google play store,下载安装,并在Google play store中点击打开,正常打开A并跳转至推广页面
  3. 用户未安装A,点击Facebook广告链接,打开Google play store,下载安装,回到桌面点击A,正常打开A并跳转至推广页面
    实现1,只需要实现Meta中的Deep Link
    实现2、3则需要在实现Deep Link的基础外加上Deferred Deep Link

Read More

不动态创建链接情况下在Firebase Dynamic Link获取动态参数

在使用Firebase的Dynamic Links做运营时,需要在链接中带去不同的参数,APP做不同的响应。如,在链接中带商品ID,用户点击不同链接进入不同商品详情页。Firebase中有两种方法可以实现。
1、创建动态链接
创建动态链接-简介
2、通过动态链接参数来实现不创建动态链接APP接收自定义参数目的。缺点就是短链接变成了长链接。
下面看看做实验的demo
这是之前建立的链接
链接详情

Read More

如何找出so依赖来源

问题

上架Google Play时提示引用了有缺陷的OpenSSL版本
缺陷的库

解决思路

  • 找出该so属于哪个库
  • 升级或如何排除该so

找出so属于哪个库

在app下的build.gradle中添加如下代码

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
//列出所有包含有so文件的库信息
tasks.whenTaskAdded { task ->
if (task.name.contains("DebugNativeLibs")) {
task.doFirst {
println("------------------- find so files start -------------------")

it.inputs.files.each { file ->
printDir(new File(file.absolutePath))
}

println("------------------- find so files end -------------------")
}
}
}

def printDir(File file) {
if (file != null) {
if (file.isDirectory()) {
file.listFiles().each {
printDir(it)
}
} else if (file.absolutePath.endsWith(".so")) {
println "find so file: $file.absolutePath"
}
}
}

Read More