随记

......

sheet中的单位

统一使用EMU

1EMU = (1 / 914400) US inch = (1 / 360000) cm

PIXEL_DPI = 96

POINT_DPI = 72

emu = (pixel / 96) * 914400

emu = (point / 72) * 914400

1 pixel = (914400 / 96 ) = 9525 emu

1 point = (914400 / 72) = 12700 emu

7 is single char pixel 

cell width:

((8*7+5)/7*256)/256 = 8.714285714

width to pixel:

(((256*8.714285714+(128/7))/256)*7) = 61.499999998

pixel to char width


31 is single char pixel

cell width:

((8*32+8)/32*256)/256

((8*32+5)/32*256)/256 = 8.15625

width to pixel:

(((256*8.15625+(128/32))/256)*32) = 261.5

字体像素计算

计算

using System;
using System.Drawing;
using System.Drawing.Text;
using System.IO;
using System.Text;
using System.Windows.Forms;
namespace FontMesure
{
public partial class FontMeasure : Form
{
int[] _font_size = new int[] { 6, 8, 9, 10, 11, 12, 14, 16, 18, 20, 22, 24, 26, 28, 36, 48, 72 };
FontStyle[] _font_style = new FontStyle[] { FontStyle.Regular, FontStyle.Bold, FontStyle.Italic };
String fontSizeDelimeter = "|";
String fontDelimeter = "__";
String fontPixelStr = "";
public FontMeasure()
{
InitializeComponent();
dumpToTxt.Enabled = false;
}

private void Form1_Load(object sender, EventArgs e)
{
Bitmap bm = new Bitmap(10, 10);
bm.SetResolution(96, 96);
Graphics g = Graphics.FromImage(bm);
InstalledFontCollection fonts = new InstalledFontCollection();
StringBuilder str = new StringBuilder(2000);
foreach (FontFamily family in fonts.Families)
{
str.Append(family.Name);
str.Append("\n");
foreach (FontStyle style in _font_style)
{
str.Append(style.ToString());
str.Append("@");
foreach (int fontSize in _font_size)
{
Font tmp = new Font(family.Name, fontSize, style);
float w = 0;
for (int i = 0; i < 10; i++)
{
SizeF sf = g.MeasureString(i + "", tmp, Int32.MaxValue, StringFormat.GenericTypographic);
if (sf.Width > w)
{
w = sf.Width;
}
}
str.Append(fontSize + ":" + w +fontSizeDelimeter);
}
str.Remove(str.Length - 1, 1);
str.Append("\n");
}
str.Append(fontDelimeter);
str.Append("\n");
}
fontPixelStr = str.ToString();
richTextBox1.Text = fontPixelStr;
g.Dispose();
dumpToTxt.Enabled = true;
}

private void richTextBox1_TextChanged(object sender, EventArgs e)
{

}

private void dumpToTxt_Click(object sender, EventArgs e)
{
TextWriter textWriter = new StreamWriter("fontPixelRaw.txt", false);
textWriter.Write(fontPixelStr);
textWriter.Close();
}
}
}

转json


import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONObject;

import java.nio.charset.StandardCharsets;

public class FontMeasureBuild {
public static void main(String[] args) {
//把上面输出的fontPixelRaw.txt 转成json格式
String raw = FileUtil.readString("fontPixelRaw.txt", StandardCharsets.UTF_8);
String[] rawSplit = raw.split("\r\n__\r\n");
JSONObject fontMapping = new JSONObject();
for (String fontRaw : rawSplit) {
if (StrUtil.isBlank(fontRaw)) continue;
String[] split = fontRaw.split("\r\n");
//font->bold->k->v
JSONObject styleMapping = new JSONObject();
fontMapping.put(split[0], styleMapping);
String[] RegularSplit = split[1].split("@");
buildFontStyleMapping("r", styleMapping, RegularSplit[1]);

String[] BoldSplit = split[2].split("@");
buildFontStyleMapping("b", styleMapping, BoldSplit[1]);


String[] ItalicSplit = split[3].split("@");
buildFontStyleMapping("i", styleMapping, ItalicSplit[1]);
}
FileUtil.writeString(fontMapping.toJSONString(),"fontPixel.json","utf8");
System.out.println(fontMapping.toJSONString());
}

public static void buildFontStyleMapping(String style, JSONObject styleMapping, String strList) {

String[] split = strList.split("\\|");
for (String str : split) {
if (StrUtil.isNotBlank(str)) {
String[] sizeSplit = str.split(":");
String key = style + "@" + sizeSplit[0];
styleMapping.put(key, sizeSplit[1]);
}
}
}

使用

根据workbook中的字体查表获取对应的digitWidth、cellWidth、cellPixelWidth


Font font = workbook.getFontAt(0);
String defaultFontName = "Calibri";
String fontName = font.getFontName();
short fontSize = font.getFontHeightInPoints();
JSONObject fontPixelConfig = JSON.parseObject(FileUtils.readStr("fontPixel.json"))
JSONObject jsonObject = fontPixelConfig.getJSONObject(fontName);
if (null == jsonObject) {
jsonObject = fontPixelConfig.getJSONObject(defaultFontName);
}
if (null != jsonObject) {
//fontStyle(Initial)@fontSize
String key = "r@" + fontSize;
String digitWidthStr = jsonObject.getString(key);
if (!StringUtils.isEmpty(digitWidthStr)) {
int dw = ColumnHelper.round(new BigDecimal(digitWidthStr).floatValue());
int cellWidthPixel = ColumnHelper.dw2pixel(dw);
float cellWidth = ColumnHelper.pixel2cw(cellWidthPixel, dw);

}
}

转换



import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTCol;

import java.math.BigDecimal;
import java.math.RoundingMode;

public class ColumnHelper {

public static int round(float v) {
return (int) (v + 0.5f);
}

/**
* @param dw_ digit width
* @return default cell width of pixel
*/
public static int dw2pixel(float dw_) {
int dw = round(dw_);
return align(Math.round(dw * 8f + round((dw) / 4f) * 2 + 1), 8);
}

/**
* @param cw cellWidth
* @param dw_ digitWidth
* @return cell width of pixel
*/
public static int cw2pixel(double cw, float dw_) {
int dw = round(dw_);
return (int) Math.round(cw * dw + round(((dw) / 4f)) * 2d + 1d);
}

/**
* @param pixel cell width of pixel
* @param dw_ digit width
* @return cellWidth of pixel
*/
public static float pixel2cw(int pixel, float dw_) {
int dw = round(dw_);
BigDecimal value = BigDecimal.valueOf(pixel - (((dw) / 4f) * 2 + 1));
value = value.divide(BigDecimal.valueOf(dw), 2, RoundingMode.HALF_UP);
return value.floatValue();
}

/**
* 按给定倍数对齐
*
* @param v 给定值
* @param a 倍数
* @return
*/
public static int align(int v, int a) {
return (v + a - 1) & -a;
}

public static float getCellWidthPixel(Sheet sheet, int colIndex) {
WorkbookInfo workBookInfo = JxlsDrawingContextHolder.getWorkBookInfo();
if (sheet instanceof XSSFSheet) {
CTCol col = ((XSSFSheet) sheet).getColumnHelper().getColumn(colIndex, false);
return (float) (col == null || !col.isSetWidth() ? workBookInfo.getDefaultColumnPixelWidth() : cw2pixel(col.getWidth(), workBookInfo.getDigitWidth()));
} else {
return workBookInfo.getDefaultColumnPixelWidth();
}
}


public static void main(String[] args) {
float dw = 32;
int pixel1 = dw2pixel(dw);
System.out.println(pixel1);//280
System.out.println(pixel2cw(pixel1, dw));//8.22
}


}


Reference

Excel列宽像素值计算方法详解

precisely-placing-images-in-an-open-xml-spreadsheet

ooxml-viewer

Calculating-Cell-Sizes

Convert Excel column width between characters unit and pixels (points)

准备工作

配置

下载MySQL源码成功后,导入到Clion

还需要做如下配置

配置Profile

File | Settings | Build, Execution, Deployment | CMake

点击+号生成了一个Profile

Name:Debug

Build type:Debug

1

CMake options 输入-DDOWNLOAD_BOOST=1 -DWITH_BOOST=boost/boost_1_59_0/

配置Toolchains

File | Settings | Build, Execution, Deployment | Toolchains

点击+号,选择Visual Studio,Clion应该会自动识别到vs2017

2

cmake

上述准备工作完成后,clion应该会自动cmake,由于boost文件较大,下载速度很慢,这个时候,只需要停止cmake.

在源码目录下找到cmake-build-debug\boost\boost_1_59_0这个目录,把上面下载好的boost_1_59_0.tar.gz文件复制过去,然后重新cmake。

不出意外的话,cmake完成后,找到任意源码文件,ctrl+鼠标左键是可以做到跳转的。

特别注意

MySQL的源码路径不能有空格或者中文

导入

mysql shell

mysql -uroot -p123456
create database test;
use test;
source test.sql;

cmd

mysql -uroot -p123456 dbname < test.sql

导出

整个数据库

mysqldump -u username -p password database_name > output.sql

导出一个表

mysqldump -u username -p password database_name table_name > output.sql

后端

java

mybatis

查看最终mapper方法生成的SQL

org.apache.ibatis.binding.MapperMethod#execute
org.apache.ibatis.executor.ReuseExecutor#doUpdate
org.apache.ibatis.executor.ReuseExecutor#doQuery

JEPaaS商业开发版部署教程

源码下载 && 基础环境搭建

前置要求

  • OS: windows/linux/macos

  • MySQL 5.7+

  • Redis 3.0+

  • Tomcat 7.0+

源码下载

  1. 下载商业开发板源码

数据库初始化

依次创建instant,jepaas 数据库,到jepaas-commercial\scripts\db-migration,把需要的脚本导入到Mysql执行

搭建redis

Redis 搭建成功后,需要在redis.conf 设置redis的密码,这里假设为 edtest123

参数修改 && 证书覆盖

  1. JEPaaS的授权证书重命名为je.license,复制到jepaas-commerical/je-web/src/main/webapp/JE/data/config目录下

  2. jepaas-commerical/je-web/src/main/resources/目录下为各个环境的配置文件,根据实际的MySQL、Redis 配置,修改jdbc.properties,redis.properties中的连接地址和认证参数

  3. scripts/push目录下是connector-serverinstant-push-server的构建好的文件,也需要修改mysql和redis 连接及认证参数

打包

-P 后面的参数代表maven打包时使用的profile,根据不同环境选择相应的profile,下面以prod为例

cd jepaas-commercial
mvn package -P prod

上述命令如果执行成功后,应该会输出一个war包jepaas-commercial\je-web\target\jepaas.war

部署 && 启动

  1. 启动 connector-serverinstant-push-server

  2. 下载tomcat后,把上面打包好的jepaas.war复制到TOMCAT_HOME\webapps\这个目录,然后把jepaas.war重命名为ROOT.war

  3. TOMCAT_HOME\bin\目录下,执行如下命令,启动服务

startup.sh

JePaaS-license加密分析

uncode-session.jar

MUserCanvas

errorInfo.json

{
"e1": "没有找到证书,请联系官方或下载证书!",
"e2": "获取认证信息出错!",
"e3": "您的证书最多创建%s张表!",
"e4": "您的证书最多创建%s个功能!",
"e5": "您的证书最多创建%s个流程!",
"e6": "证书认证异常!",
"e7": "学习版无法使用迁移工具,请购买指定的授权!",
"e8": "您的版本用户量超过限制!",
"e9": "您的证书已到期,请联系官方!",
"e10": "您的版本资源已超过限制,将无法启动!",
"e11": "授权告警!",
"e12": "请更新插件集!"
}

  • g 错误信息JSON
  • name license信息
  • s plugin.lock 信息
  • e 可创建表数量,-1 无限制
  • h 可创建流程数量,-1无限制
  • f 可创建功能数量,-1无限制
  • q 最大用户数量,-1无限制
  • i 证书到期时间
  • x 版本:develop开发版,commercial商业版
  • m 版本号
  • 。。

je.license定义

  • d RSA privateKey
  • b AES key
  • a AES IV
  • c AES 加密后的内容

plugin.lock定义

  • d RSA privateKey
  • b AES key
  • a AES IV
  • c AES 加密后的内容

je.license 解密前

{
"a": "Eu0KOoPjqTOWZKeEOyyIJcr6RTBchmdMVSJi0aX7oQEM5wcBKsTrUlHg0mdQS3wsPOc/LSKswc7IPAd1U/OE5GVhOkerLiPZgouIqXNVMIvfhH1RS5nXHkHtdHS1HVAkEUEZ9PA0EAZtBYdqYbUm1wHEBvBnGUoyHDP1ymVBQw8=",
"b": "QNu+ipkXIXXYZZkZczDUNTYfV60QimrI8nVxmoxKuBVJtnzC7YJo9O0wHrLYe0+iGQZy/qj4UZVlMdNc2qwpx4b03Orqu+c6qfp2L5befTH3AwDOT146OMx8F/dIRQ6KYmwuAGT5+zozw8K3BKA+WCrjuWYuK7BuuEld8OWQpMo=",
"c": "fkFTsuZi8C+f+zvfXPO/I4cm4bLdJdYP1P11HiJ9xAjUIlmc/TMS3yinyHGolZ6tjEYvLF3AUzzN3+HbQQn2jFvRldwZAPQzkS2iuG7wLiwzTwGxkBFk+6J2GCCQxzgFDcXIfxIFFB1YOqFnje2wiKW6viPQqQBFu2FniW57bHzH+7qAcNmZBewTE4REbMYfqUm7spbRvrr09kgaKmD0HmJBejVIulMoxBUFmSgqnW9ywPuToUwTB81OiqVPUqAvdsOwzxJnkQQRn2Pt0WzEdDbbAdONyWcZw3dc5sEKMz3U6lD5GUPPZi/Yn0QwHOZDQuxJ3dIliQ05vVDhIH2txLa58Cyuzw6UI2sMIWc4KlJm7sa3hlvz9bvkPE5FJUHx2fw+DLx8hszJ/g9+d7DnS1fM2YRgV8R7SuPXDZ9Yx/u7IUlNwbZiyyh1o8X9dQND5C98VDH34Q8twj4AiNqtOjX4prx6jvHMIYCv/eou/g7lHxWTwJ08kfFbKbpBUSmiedcHqLnAL8izdRHvUUlDBw==",
"d": "MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAIOKUqPHeVESjR47ptAd+BBBJUoVDfYkaMMrTUWIDQrO1OW1LPUYvLUXnrkePftmR1saeMyIKWaJX08dKqSKto5WJr/E6GD9/YADMlph1ZC2LGxFqDg8hgK2dqfcNMVuobIOFuBSjcFr5QKFcdchkNVC4ULtuoabFg8knoH2tnJPAgMBAAECgYAculPsEv+K1jtds/dtkm3/1sp3EHwZGsCKh2V73wfCKYPTmyrzaHCmOD9g/Jra0e6ZlgF14fLwwuW+2IbcorLVuOFg6WRmlLm21jb+IDIvdfsrkccH17ukuGjxT548QVmS/6axv/rtmaBqI8YvlQq4BSl+vvcacUMQnRmy4dJMWQJBAMR9l2zQjDYdUoahskMInpcCgDxGTbKNpyNiIBvArBG0cLghrOlQYC7NF8j/87HWRZxAeRf6Kls4KRxjMhrl+z0CQQCrYPlcs7mAqrmIsdjENAcrnnA7WEO9Zq/1fn2wnWHBIFS4UUmvTenytLnsGtTouJeznzK+vCrzF3mtQjvsrWx7AkBIXqGJGH6r57zfjWqkueX/ZJJqoNI5M2cd5yRAVISLuNPTXcPb4xip5CwggfT1yR+2XyC6rg8vrc2mgPqRYadZAkBE/R6k0LymLRPPETjfksooJvmrChcK0aGXw7m5NUG6ytcP87kj1suMpnAJuatnm5eF+VomKf1oKlUTCAyzdAStAkEAgyqG6NpVX9x39UpEZ5/Nk8NxUQdZxFVGT0vaFPE1qWUWriDUwSQx02N7LAUYhjlxuUtWjmms+IfiJV7DAvTOZg=="
}

解密算法

function rsaDecrypt(data){
return Crypto.rsaDecrypt(data);
}
const licenseInfo = Base64.decode(readFile("je.license")).toJSON();
const rsaPrivateKey = Crypto.genRSAPrivateKey(licenseInfo.d);
const aesKey = Crypto.aesKey(rsaDecrypt(licenseInfo.b));
const aesIV = Crypto.aesIV(rsaDecrypt(licenseInfo.a));
const result = Crypto.aesDecrpyt(aesKey,aesIV,licenseInfo.c);

解密后:

{
"a": "技术支持:凯特伟业",//topInfo
"b": "JEPAAS快速开发平台系统加载中...",//loadingInfo
"c": "北京凯特伟业提供技术支持 电话:400-0999-235", //companyInfo
"d": "",
"e": -1,//tableNum
"f": -1,//funNum
"h": -1,//proceeNum
"i": "-1",//
"j": "2020-08-19 16:13:33",//createdTime
"k": "http://jepaas.com",
"m": "v2",//pluginVersion
"n": "2021-05-10 17:39:14",//verifyTime
"o": "1888-6430-1121-8706",//verifyUniqueCode
"q": -1,//userNum
"r": "刘旭",//applicant
"t": "0",//auth
"v": "",//
"w": "2019-07-20 12:04:36",
"x": "develop",//licenseType
"y": 50,//machineNum
"z": "2.0"//licenseVersion
}

{
"success": true,
"obj": {
"userNum": "-1",
"auth": "1",
"companyInfo": "北京凯特伟业提供技术支持 电话:400-0999-235",
"machineNum": "50",
"loadInfo": "JEPAAS快速开发平台系统加载中...",
"topInfo": "技术支持:凯特伟业",
"verifyTime": "2021-12-31 17:49:02",
"applicant": "刘旭",
"licenseType": "develop",
"creatTime": "2020-08-19 16:13:33",
"funNum": "-1",
"tableNum": "-1",
"licenseVersion": "2.0",
"verifyUniqueCode": "6468-3423-1654-5339",
"processNum": "-1"
}
}

plugin.lock解码前

{
"a": "QruKKDuCwU9+ohAcw/NbZO47YTsOngaMrosHHOH9QDz3AwuQCsFfZ0K4FdyNIIcNfAygRNku4bts8AkOt1TLsT/vewr5SM2alkexCw101WedAQatYtMZt44FeqpBqWh3zSRcB7FAxySvS6Q+dEHtWsCoWxlW/xvNew+TASe9+OU=",
"b": "RHGz4esnrLvFLyMsRm2tVDNuIvGMAPE8X9vhQ0XhqI7sU/dCJ5XRf+7W5wuw5qLgzVmR6R8K6dFAgZn/oU5sHA3d5VUs3bSnq+BCNZoMBU1RQDhEixzzf9wfLuLtsrLX/gc5m4oK8+gu3PEZLuXgdHyV/5tLo0pOFVrEMPr9Btk=",
"c": "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",
"d": "MIICdQIBADANBgkqhkiG9w0BAQEFAASCAl8wggJbAgEAAoGBAI2aNFu1vfjI7Iy+yQVDFFvAteIBMTGCUKj9BPER444SoQ2tfclNgsmEWwtZmqMb6rbw8s9k02NqDX4UMjuC5uQsqKCEE9i9/aHBlbRiPt2ANmvPxfTCml5Kh1sQkaUZo6fRmAUtQpuDSDl2CYrXe5w8Is/MEScVA2oFiAioydS5AgMBAAECgYBvFvZSqK9kOYVTGe4tAaY8IWDP8O1+EOVk3jN9SPKEKFtPlrdjMTsVC5A9xEtMAX/PjBKB4HDywmXZbtDF3XlziAtWgcvTE7jdjwKVXHngMWFKFndLzwVqnAVBFEhtX+HSOWnewxg3w0FHFhdsJeluwGoXLuJJZPiw6d8zoJc/fQJBAMbgDzeJSK2jSz8a0LFmXAQEJs536PDIrlKxxF3qnh7HMHy0PzkBFwNdyyrpV5bIwSbq0vIG8FMIzebRemfMRxsCQQC2Rq9qtoD9TFXX1f1xPyGqjeW/D6WWWkkeKLlcEEMXSS3ZV9M2r+PKyocxKtB+6hxGX4I94NihtskExDiGX+y7AkBp7U/Nmd7PNanPm93Kj6W1MezljjLRhWJsg2j/SQcdh6UI1wzRtQXn8h5T5eOUWaufqfXfmdiJsafSKINVJBY/AkAmtxzLLbh4FJ6nGWybgS1FbJ4/1rL1HHgrT7sPMuUNLR3v7BeQpgtcJ2hPqShfzJn02JRxUDCzKH/J42OeJwHBAkAOP5F3BKXtk1qlMxmuTbDQqTPiFEIfQ5/7BI3oWJzQUBJXfL2bKyRw0Kv4TiZCaduOjqUa6WSY5oCkrGLxNTkJ"
}

解密后

{
"p": [
{
"a": "JE_CORE_THIRDSOURCE",
"b": "0",
"c": "FUNC",
"f": "[{\"model\":\"MENU\",\"type\":\"MT\",\"info\":\"JE_CORE_THIRDSOURCE\"}]",
"g": "plugin7.key"
},
{
"a": "JE_INSTANT_MESSAGE",
"b": "0",
"c": "FRONTEND",
"f": "[{\"model\":\"DOM\",\"type\":\"IM\",\"info\":\".im-content .im-text\"}]",
"g": "plugin5.key"
},
{
"a": "JE_CORE_MESSAGE",
"b": "0",
"c": "FRONTEND",
"f": "[{\"model\":\"MENU\",\"type\":\"MT\",\"info\":\"JE_CORE_PUSH_TEMPLATE\"}]",
"g": "plugin27.key"
},
{
"a": "JE_CORE_INDUSTRY",
"b": "0",
"c": "FRONTEND",
"f": "[{\"model\":\"MENU\",\"type\":\"MT\",\"info\":\"JE_CORE_INDUSTRY\"},{\"model\":\"VIEW\",\"info\":\"JE.sys.svg.view.MainView\"}]",
"g": "plugin22.key"
},
{
"a": "JE-CORE-DESKTOP",
"b": "0",
"c": "FRONTEND",
"f": "[{\"model\":\"MENU\",\"type\":\"MT\",\"info\":\"JE_DESKTOP_UPGRADE\"}]",
"g": "plugin18.key"
},
{
"a": "JE_SYS_TIMEDTASK",
"b": "0",
"c": "FUNC",
"f": "[{\"model\":\"MENU\",\"type\":\"MT\",\"info\":\"JE_SYS_TIMEDTASK\"}]",
"g": "plugin6.key"
},
{
"a": "JE_CORE_PERMLIST",
"b": "0",
"c": "FUNC",
"f": "[{\"model\":\"MENU\",\"type\":\"IDDT\",\"info\":\"JE_ADMINPERM,JE.sys.rbac.view.perm.MainView\"}]",
"g": "plugin8.key"
},
{
"a": "JE_CORE_EXCELGROUP",
"b": "0",
"c": "FUNC",
"f": "[{\"model\":\"MENU\",\"type\":\"MT\",\"info\":\"JE_CORE_EXCELGROUP\"}]",
"g": "plugin13.key"
},
{
"a": "JE-CORE-THIRD",
"b": "0",
"c": "FUNC",
"f": "[{\"model\":\"MENU\",\"type\":\"MT\",\"info\":\"JE_CP_APP\"},{\"model\":\"MENU\",\"type\":\"MT\",\"info\":\"JE_CP_DEPT\"},{\"model\":\"MENU\",\"type\":\"MT\",\"info\":\"JE_CP_DEPTUSER\"},{\"model\":\"MENU\",\"type\":\"MT\",\"info\":\"JE_FS_DEPT\"},{\"model\":\"MENU\",\"type\":\"MT\",\"info\":\"JE_FS_DEPTUSER\"},{\"model\":\"MENU\",\"type\":\"MT\",\"info\":\"JE_DD_DEPT\"},{\"model\":\"MENU\",\"type\":\"MT\",\"info\":\"JE_DD_DEPTUSER\"},{\"model\":\"MENU\",\"type\":\"MT\",\"info\":\"JE_SERVER_DETAIL\"}]",
"g": "plugin19.key"
},
{
"a": "JE_CORE_DATAFLOW",
"b": "0",
"c": "CONFIG",
"f": "[{\"model\":\"FUNC\",\"type\":\"CONFIG\",\"info\":\"JE_DataflowConfig\"},{\"model\":\"VIEW\",\"info\":\"JE.sys.funccfg.view.data.DataFlowView\"}]",
"g": "plugin17.key"
},
{
"a": "JE_CHINA_JINCANG",
"b": "0",
"c": "BACKEND",
"f": "{\"className\":\"\"}",
"g": "cplugin2.key"
},
{
"a": "JE_CORE_COMMON_PERM",
"b": "0",
"c": "FUNC",
"f": "[{\"model\":\"MENU\",\"type\":\"IDDT\",\"info\":\"JE_PUBLICPERM,JE.sys.rbac.view.public.MainView\"}]",
"g": "plugin9.key"
},
{
"a": "JE_CORE_NEWS",
"b": "0",
"c": "FRONTEND",
"f": "[{\"model\":\"VIEW\",\"info\":\"PRO.portal.View\"}]",
"g": "plugin1.key"
},
{
"a": "JE_CORE_DISK",
"b": "0",
"c": "FRONTEND",
"f": "[{\"model\":\"MENU\",\"type\":\"IDDT\",\"info\":\"JE_SYS_CLOUDFILE,PRO.cloud.View\"}]",
"g": "plugin16.key"
},
{
"a": "JE_CORE_MANAGERPLUGIN",
"b": "0",
"c": "FUNC",
"f": "[{\"model\":\"MENU\",\"type\":\"IDDT\",\"info\":\"JE_RBAC_CJGL,JE.sys.rbac.view.cjgl.MainView\"}]",
"g": "plugin14.key"
},
{
"a": "JE_CORE_REPORT",
"b": "0",
"c": "FUNC",
"f": "[{\"model\":\"MENU\",\"type\":\"IDDT\",\"info\":\"JE_CORE_CHARTS,JE.sys.chart.view.MainView\"},{\"model\":\"VIEW\",\"info\":\"JE.core.view.ChartView\"},{\"model\":\"VIEW\",\"info\":\"JE.core.view.ReportView\"}]",
"g": "plugin11.key"
},
{
"a": "JE_CHINA_DAMENG",
"b": "0",
"c": "BACKEND",
"f": "{\"className\":\"\"}",
"g": "cplugin3.key"
},
{
"a": "JE_CORE_IOT",
"b": "0",
"c": "BACKEND",
"f": "[{\"model\":\"MENU\",\"type\":\"MT\",\"info\":\"JE_WLW_KHD\"},{\"model\":\"MENU\",\"type\":\"MT\",\"info\":\"JE_WLW_EQUIPMENT\"}]",
"g": "plugin24.key"
},
{
"a": "JE_CORE_JEAPPH5",
"b": "0",
"c": "FRONTEND",
"f": "[]",
"g": "plugin26.key"
},
{
"a": "JE_CORE_BUSFLOW",
"b": "0",
"c": "FUNC",
"f": "[{\"model\":\"MENU\",\"type\":\"MT\",\"info\":\"SYSZ_FLOWINFO\"}]",
"g": "plugin10.key"
},
{
"a": "JE_CORE_DATASOURCE",
"b": "0",
"c": "FUNC",
"f": "[{\"model\":\"MENU\",\"type\":\"MT\",\"info\":\"JE_CORE_DATASOURCE\"}]",
"g": "plugin3.key"
},
{
"a": "JE_CORE_UPPACKAGE",
"b": "0",
"c": "FUNC",
"f": "[{\"model\":\"MENU\",\"type\":\"MT\",\"info\":\"JE_CORE_UPPLATFORM\"},{\"model\":\"MENU\",\"type\":\"MT\",\"info\":\"JE_CORE_UPPACKAGE\"}]",
"g": "plugin2.key"
},
{
"a": "JE_CHINA_SHENTONG",
"b": "0",
"c": "BACKEND",
"f": "{\"className\":\"\"}",
"g": "cplugin1.key"
},
{
"a": "JE_CORE_PROTAL",
"b": "0",
"c": "FUNC",
"f": "[{\"model\":\"MENU\",\"type\":\"MT\",\"info\":\"JE_CORE_PROTAL\"},{\"model\":\"VIEW\",\"info\":\"JE.sys.portal.view.MainView\"},{\"model\":\"VIEW\",\"info\":\"JE.core.view.PortalView\"},{\"model\":\"VIEW\",\"info\":\"JE.core.view.PortalMenuView\"}]",
"g": "plugin15.key"
},
{
"a": "JE_CORE_TIDB",
"b": "0",
"c": "BACKEND",
"f": "[]",
"g": "plugin23.key"
},
{
"a": "JE_FUNCCONFIG_DATAPERM",
"b": "0",
"c": "CONFIG",
"f": "[{\"model\":\"FUNC\",\"type\":\"CONFIG\",\"info\":\"JE_DataConfig\"},{\"model\":\"VIEW\",\"info\":\"JE.sys.funccfg.view.power.PowerView\"}]",
"g": "plugin12.key"
},
{
"a": "JE_CORE_PHONE",
"b": "0",
"c": "FRONTEND",
"f": "[{\"model\":\"MENU\",\"type\":\"IDDT\",\"info\":\"JE_PHONE_APP,JE.sys.phone.view.ApkView,JE.sys.phone.controller.MainController\"},{\"model\":\"MENU\",\"type\":\"MT\",\"info\":\"JE_PHONE_UPGRADE\"},{\"model\":\"MENU\",\"type\":\"MT\",\"info\":\"JE_PHONE_FUNC\"},{\"model\":\"MENU\",\"type\":\"MT\",\"info\":\"JE_PHONE_PLUGIN\"},{\"model\":\"MENU\",\"type\":\"MT\",\"info\":\"JE_PHONE_LOGGER\"}]",
"g": "plugin4.key"
}
],
"b": "v7.2.7"
}

logging:
file:
name: logs/etc-service/etc-service.log #日志文件名称
max-size: 50KB #单个日志文件最大大小
max-history: 7 #日志归档保留天数
level:
root: info
org.hibernate.type.descriptor.sql.BasicBinder: trace
com.netflix.eureka: OFF
com.netflix.discovery: OFF
org.springframework.cloud.config.client.ConfigServicePropertySourceLocator: WARN
pattern:
#rolling-file-name: ${LOG_FILE}.%d{yyyy-MM-dd}.%i.log #滚动日志文件名称pattern,当文件已gz,zip结尾时,日志文件会被压缩
rolling-file-name: logs/etc-service/%d{yyyy-MM-dd,aux}/etc-service.%d{yyyy-MM-dd}.%i.log #滚动日志文件名称pattern,当文件已gz,zip结尾时,日志文件会被压缩

JOL

简介

JOL(Java Object Layout)是用于分析 JVM 中对象布局方案的微型工具箱。这些工具大量使用 Unsafe、JVMTI 和 Serviceability Agent (SA) 来解码实际的 对象布局、占用空间和引用。这使得JOL比其他依赖堆转储、规范假设等的工具更准确。

使用

测试类

public class SimpleObject {
//primitive type
private byte b;
private boolean bl;
private short s;
private char c;
private int a;
private float f;
private double d;
private long l;
//reference type
private Object obj;
private Object [] objArray;
}

测试代码


/**
* 打印class布局
*/
public void testPrintClassLayout(){
ClassLayout classLayout = ClassLayout.parseClass(SimpleObject.class);
System.out.println(classLayout.toPrintable());
}

/**
* 打印对象实例布局
*/
public void testPrintObjectLayout(){
SimpleObject obj = new SimpleObject();
System.out.println(ClassLayout.parseInstance(obj).toPrintable());
}

关闭指针压缩

VM参数:-XX:-UseCompressedOops

Class Layout

SimpleObject object internals:
OFF SZ TYPE DESCRIPTION VALUE
0 8 (object header: mark) N/A
8 8 (object header: class) N/A
16 8 double SimpleObject.d N/A
24 8 long SimpleObject.l N/A
32 4 int SimpleObject.a N/A
36 4 float SimpleObject.f N/A
40 2 short SimpleObject.s N/A
42 2 char SimpleObject.c N/A
44 1 byte SimpleObject.b N/A
45 1 boolean SimpleObject.bl N/A
46 2 (alignment/padding gap)
48 8 java.lang.Object SimpleObject.obj N/A
56 8 java.lang.Object[] SimpleObject.objArray N/A
Instance size: 64 bytes
Space losses: 2 bytes internal + 0 bytes external = 2 bytes total

Object Layout

SimpleObject object internals:
OFF SZ TYPE DESCRIPTION VALUE
0 8 (object header: mark) 0x0000000000000001 (non-biasable; age: 0)
8 8 (object header: class) 0x000000001c123380
16 8 double SimpleObject.d 0.0
24 8 long SimpleObject.l 0
32 4 int SimpleObject.a 0
36 4 float SimpleObject.f 0.0
40 2 short SimpleObject.s 0
42 2 char SimpleObject.c
44 1 byte SimpleObject.b 0
45 1 boolean SimpleObject.bl false
46 2 (alignment/padding gap)
48 8 java.lang.Object SimpleObject.obj null
56 8 java.lang.Object[] SimpleObject.objArray null
Instance size: 64 bytes
Space losses: 2 bytes internal + 0 bytes external = 2 bytes total

开启指针压缩

默认是开启的

VM参数:-XX:+UseCompressedOops

uid:8个字节
timpstamp:8个字节
Map每个Node大小
4+8+8+4
hash(4) + key(8) + value(8) +next(4)
每个用户占用16个字节

Class Layout

SimpleObject object internals:
OFF SZ TYPE DESCRIPTION VALUE
0 8 (object header: mark) N/A
8 4 (object header: class) N/A
12 4 int SimpleObject.a N/A
16 8 double SimpleObject.d N/A
24 8 long SimpleObject.l N/A
32 4 float SimpleObject.f N/A
36 2 short SimpleObject.s N/A
38 2 char SimpleObject.c N/A
40 1 byte SimpleObject.b N/A
41 1 boolean SimpleObject.bl N/A
42 2 (alignment/padding gap)
44 4 java.lang.Object SimpleObject.obj N/A
48 4 java.lang.Object[] SimpleObject.objArray N/A
52 4 (object alignment gap)
Instance size: 56 bytes
Space losses: 2 bytes internal + 4 bytes external = 6 bytes total

Object Layout

SimpleObject object internals:
OFF SZ TYPE DESCRIPTION VALUE
0 8 (object header: mark) 0x0000000000000001 (non-biasable; age: 0)
8 4 (object header: class) 0xf800c105
12 4 int SimpleObject.a 0
16 8 double SimpleObject.d 0.0
24 8 long SimpleObject.l 0
32 4 float SimpleObject.f 0.0
36 2 short SimpleObject.s 0
38 2 char SimpleObject.c
40 1 byte SimpleObject.b 0
41 1 boolean SimpleObject.bl false
42 2 (alignment/padding gap)
44 4 java.lang.Object SimpleObject.obj null
48 4 java.lang.Object[] SimpleObject.objArray null
52 4 (object alignment gap)
Instance size: 56 bytes
Space losses: 2 bytes internal + 4 bytes external = 6 bytes total

指针压缩对结果的影响

以下都是基于64bit操作系统的测试结果

开启指针压缩 关闭指针压缩
对象头 12byte 16byte
引用类型 4byte 8byte

其他

对象的大小是8的倍数,如果不是8的倍数,jvm在创建对象分配内存时会填充字节用以对齐

JUC lock与synchronized 差异

线程状态

    // Thread State
    // ReentrantLock.lock ->  java.lang.Thread.State: WAITING (parking)
    waiting on condition
    // synchronized ->  java.lang.Thread.State: BLOCKED (on object monitor) waiting for monitor entry
    // get lock on sleep ->  java.lang.Thread.State: TIMED_WAITING (sleeping)

取最小记录

没有比它更小的记录,那么就是最小记录

select v1.id,v2.id from certification_version v1 left join certification_version v2 on v1.certification_id = v2.certification_id
and v1.deleted = 'f'
and v2.created_time < v1.created_time
where 1=1
--and v1.id ='d0196569-393d-4bb1-a843-7b058efca61d'
and v2.id is null
and v1.certification_id = 'c1bb788b-cce3-4377-baae-53e4b4f589d8'

取最大记录

没有比它更新的记录,那么它就是最新记录

select v1.id,v2.id from certification_version v1 left join certification_version v2 on v1.certification_id = v2.certification_id
and v1.deleted = 'f'
and v1.created_time < v2.created_time
where 1=1
--and v1.id ='d0196569-393d-4bb1-a843-7b058efca61d'
and v2.id is null
and v1.certification_id = 'c1bb788b-cce3-4377-baae-53e4b4f589d8'

redis token store key specs

access: 
accessToken-> OAuth2AccessToken

auth:
accessToken -> OAuth2Authentication

auth_to_access:
md5(OAuth2Authentication -> {username=xxx,client_id=xxx,scope=xxx}) -> OAuth2AccessToken

uname_to_access: Set
clientId +":"+ username(phone) -> OAuth2AccessToken

client_id_to_access: Set
clientId -> OAuth2AccessToken

refresh_to_access:
refreshToken -> OAuth2RefreshToken

access_to_refresh:
accessToken -> refreshToken

0%