使用官方推荐的 Gradle 插件开发
这是 IDEA 插件开发第一篇, 整个系列记录了开发 aliyun-oss-upload 的整个细节, 将会把遇到的问题整理成文, 最终发布在 idea-plugin-dev 中.
前言IDEA 插件开发分为 2 种方式:
直接使用 IDEA 提供的 IntelliJ Platform Plugin
2. 使用 Gradle
官方推荐使用 Gradle 方式, 因此选用第二种方式.
因为未使用过 Gradle, 肯定会遇到很多坑, 为了减少大家爬坑的时间, 我会尽量把注释写详细点, 如果发现错误的地方, 请告知我.
配置使用 Gradle 创建好插件项目后, 直接拷贝以下配置到 build.gradle
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748// mavenCentral() 是一个插件仓库, 导入的插件将会在仓库中寻找并下载buildscript { repositories { ...
昨天做完精准营销的需求后, 提测版本一直连不上 MQ, 然后在本地启动后也未发现问题, 直到监听的消息队列有消息而且是大量消息时才会出现的错误:
1234567891011121314151617181920212223242526javax.jms.JMSException: Cannot send, channel has already failed: tcp://172.31.205.58:61616 at org.apache.activemq.util.JMSExceptionSupport.create(JMSExceptionSupport.java:62) at org.apache.activemq.ActiveMQConnection.syncSendPacket(ActiveMQConnection.java:1409) at org.apache.activemq.ActiveMQConnection.ensureConnectionInfoSent(ActiveMQConnection.java:1496) at org.apache.activemq. ...
新时代码农
未读记录 mac mini 开发环境的搭建过程
系统设置修改 Launchpad 图标大小1234567891011121314行:defaults write com.apple.dock.springboard-rows -int 7列:defaults write com.apple.dock.springboard-columns -int 9重启 dock恢复:defaults write com.apple.dock.springboard-rows defaultdefaults write com.apple.dock.springboard-columns defaultkillall dockdefaults write com.apple.dock springboard-columns -int 11;defaults write com.apple.dock springboard-rows -int 7;defaults write com.apple.dock ResetLaunchPad -bool TRUE;killall Dock
xxx.app ...
为什么用线程池
创建 / 销毁线程伴随着系统开销, 过于频繁的创建 / 销毁线程, 会很大程度上影响处 - 理效率
线程并发数量过多, 抢占系统资源从而导致阻塞
对线程进行一些简单的管理
在 Java 中, 线程池的概念是 Executor 这个接口, 具体实现为 ThreadPoolExecutor 类, 学习 Java 中的线程池, 就可以直接学习他了对线程池的配置, 就是对ThreadPoolExecutor 构造函数的参数的配置
构造函数:1234567891011121314151617181920212223242526272829303132// 五个参数的构造函数public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, ...
之前一直学习 SpringCloud, 对于配置中心,一直也是采用的 Spring Cloud Config,但是用久了,发现很多地方满足不了要求,同时也感觉很 low(个人看法勿喷)。在学习 Spring cloud config 的时候也有听到过携程的 apollo,但一直没时间去弄。直到昨天看了一张图,如下:使我下定决心去看看携程的 apollo 配置中心。
这张图也算是综合对比了 spring cloud config,netflix archaius, ctrip apollo, disconf, hawk 等配置中心的功能点。综合比较下来携程 apollo 更具有优势。
二、简单介绍携程 Apollo 配置中心1、What is Apollo1.1 背景随着程序功能的日益复杂,程序的配置日益增多:各种功能的开关、参数的配置、服务器的地址……
对程序配置的期望值也越来越高:配置修改后实时生效,灰度发布,分环境、分集群管理配置,完善的权限、审核机制……
在这样的大环境下,传统的通过配置文件、数据库等方式已经越来越无法满足开发人员对配置管理的需求。
Apollo 配置中心应运而 ...
现有架构日志存在的问题
关键逻辑无日志埋点
日志级别规范
生产环境日志级别不正确, 不规范
日志配置不统一
日志框架不统一
日志打语句不规范
因此针对以上问题, 对整个项目中的日志进行规范管理
统一日志配置新框架中统一使用 log4j2 日志框架来进行日志管理
具有的功能:
根据不同的环境输出不同的日志级别
开发环境, 输出等级为 debug
测试和生成环境, 输出等级为 info
开发环境, 只输出到 console
测试和生产环境, 输出到 /usr/logs/app_name/port/all.log, 关闭 console 输出
按天压缩日志
自动删除 30 天以前的日志
统一输出格式
动态修改日志等级
现有日志修改现在的代码暂时不能全部迁移到新框架, 考虑到现在各个模块使用的日志配置不统一, 日志配置不合理, 这里规范一下日志相关的配置
统一配置格式由于老项目中一部分使用 log4j, 另一部分又使用了 log4j2 日志框架,配置文件一部分是 xml, 另一部分又是 properties.
为了以后迁移方便, ...
新时代码农
未读开发中日志这个问题,每个公司都强调,也制定了一大堆规范,但根据实际情况看,效果不是很明显,主要是这个东西不好测试和考核,没有日志功能一样跑啊。
但是没有日志, 一旦系统出现问题, 将导致排查问题时困难重重.因此好的日志输出有利于快速定位问题
但是我们在什么时候打印日志? 需要打印什么信息? 用什么日志级别?这些问题都将应用我们排查问题时的速度
因此这里制定一个日志规范, 将日志相关的常识性问题做一个总结.
日志等级说明
trace, debug: 理论上 “不属于错误”, 只是打印一些状态, 提示信息, 以便 开发过程 中观察.
info: 理论上 “不属于错误”, 只是一些提示性的信息, 但是即使在开发完成, 正式上线的系统中, 也有保留的价值.
warn: 属于轻微的 “警告”, 程序中出现了一些异常情况, 但是影响不大, 还可以正常使用.
error: 属于 “普通的错误”, 在程序可以控制的范围内, 不会造成连锁影响或巨大影响.
fatal: 属于 “致命错误”, 可导致整个系统或者一系列功能无法使用, 甚至导致系统瘫痪, 关闭.
规范
日志必须显示 日志等级, 时间精 ...
多个模块有登录需求, 但是代码都是相互拷贝, 没有做统一处理
优化方案将登录逻辑封装成模块, 作为插件提供服务
shiro 认证过程1. 收集实体/凭据信息1UsernamePasswordToken token = new UsernamePasswordToken(username, password, true);
UsernamePasswordToken 支持最常见的用户名/密码的认证机制。同时,由于它实现了 Rarraydsj@163.comemberMeAuthenticationToken 接口,我们可以通过令牌设置“记住我”的功能。但是,“已记住 ...
需要的环境:
具有公网 IP 的服务器, 运行 proxy-server
一台内网 pc 或服务器, 运行 proxy-client
lanproxy
nginx
JDK
准备工作使用 阿里云 服务器, ip 为 111.111.111.111, 已经安装好了 nginx 和 JDK8
下载 proxy-server 和 proxy-client
https://github.com/ffay/lanproxy/releases
修改 hosts 文件
12111.111.111.111 ivr.wechat.com111.111.111.111 local.ivr.wechat.com
proxy-server 搭建
解压 proxy-server.zip
修改配置文件 conf/config.properties, 修改用户名和密码
启动服务 /usr/local/proxy-server/bin/startup.sh
config.properties
1234567891011121314151617181920server.bind=0.0.0.0# 普通端口serv ...
why为了减少日志文件的数量, 生产环境的日志等级都是 Error, 但是当遇到问题时, 错误日志可能不能快速准确的定位出错的地方, 如果能在不重启应用的情况下,修改日志级别并且生效, 能更快的发现出错的地方.
what这里选择使用 JMX 来实现日志级别动态修改.
JMX (Java Management Extensions) 是管理 Java 的一种扩展. 这种机制可以方便的管理, 监控正在运行中的 Java 程序. 常用于管理线程, 内存, 日志Level, 服务重启, 系统环境等.
实现一个被 JMX 托管的 MBean 的方式:
MBean 的接口必须以 MBean 结尾, 比如 XxxxMBean
实现必须以 Xxxx 命名因为接口定义是 XxxxMBean
logback 定义的 MBean
jconsole 查看 MBean
how动态修改日志级别的思路:
API 调用 DynamicChangeLogLevel 修改日志级别
DynamicChangeLogLevel 通过 LogBackMBean 修改日志级别
使用责任链, 修改 xxx-api ...
代码织入实现方式:
静态代理
AspectJ 织入器 weaver)
compile-time weaving 使用 aspectj 编译器进行编译源码
post-compile weaving 对 class 文件进行织入
load-time weaving(LTW) 当 class loader 加载类的时候,进行织入
动态代理
JDK 动态代理 (接口)
CGlib(类)
这里使用 AspectJ LTW 实现, 这种方式在类加载器织入代码.
编译器织入 会造成编译速度变慢, 而且必须使用 ajc 编译器
动态代理 会生成大量代理类, 加速内存消耗
因此使用 类加载期织入 相对于其他两种方式, 更加轻便.
LTW(Load Time Weaver),即加载期切面织入,是 ApsectJ 切面织入的一种方式,它通过 JVM 代理在类加载期替换字节码到达织入切面的目的。
具体实现首先定义个切面类,该切面功能非常简单,就是在 com.xxx.server.rest.resource.impl 及其所有子包下所有的类的 public 方法调用后打印执行时间
123 ...
使用 Redis Sentinel 重构现有架构
对于搭建高可用 Redis 服务,网上已有了很多方案,例如 Keepalived,Codis,Twemproxy,Redis Sentinel。其中 Codis 和 Twemproxy 主要是用于大规模的 Redis 集群中,也是在 Redis 官方发布 Redis Sentinel 之前 豌豆荚 和 twitter 提供的开源解决方案。Redis Sentinel 可以理解为一个监控 Redis Server 服务是否正常的进程,并且一旦检测到不正常,可以自动地将备份 (slave)Redis Server 启用,使得外部用户对Redis 服务内部出现的异常无感知。
原有架构
存在的问题
配置部署复杂
不稳定
Redis Sentinel 高可用
下面以 1 个主节点、2 个从节点、3 个 Sentinel 节点组成的 Redis Sentinel 为例子
故障转移处理逻辑:
主节点出现故障, 此时两个从节点与主节点时区连接, 主从复制失败;
每个 Sentinel 节点通过定期监控发现主节点出现故障;
多个 Sent ...
Jar 包冲突是老生常谈的问题,几乎每一个 Java 程序猿都不可避免地遇到过,并且也都能想到通常的原因一般是同一个 Jar 包由于 maven 传递依赖等原因被引进了多个不同的版本而导致,可采用依赖排除、依赖管理等常规方式来尝试解决该问题,但这些方式真正能彻底解决该冲突问题吗?答案是否定的。笔者之所以将文章题目起为 “重新看待”,是因为之前对于 Jar 包冲突问题的理解仅仅停留在前面所说的那些,直到在工作中遇到的一系列 Jar 包冲突问题后,才发现并不是那么简单,对该问题有了重新的认识,接下来本文将围绕 Jar 包冲突的问题本质和相关的解决方案这两个点进行阐述。
Jar 包冲突问题一、冲突的本质Jar 包冲突的本质是什么?Google 了半天也没找到一个让人满意的完整定义。其实,我们可以从 Jar 包冲突产生的结果来总结,在这里给出如下定义(此处如有不妥,欢迎拍砖 -):
Java 应用程序因某种因素,加载不到正确的类而导致其行为跟预期不一致。
具体来说可分为两种情况:1)应用程序依赖的同一个 Jar 包出现了多个不同版本,并选择了错误的版本而导致 JVM 加载不到需要的类或加 ...
新时代码农
未读整理一下项目中不好的代码写法
以下是一些具有代表性的问题, 都是一些一看就明白的问题, 还有一些代码的坑, 慢慢填吧.
只针对代码, 不针对谁, 如果写的不对的对方, 你咬我啊
代码问题还失败重试? 失败重试个啥? 直接返回了 老铁!!代码 1 后面, 获取了 batchResult, 不应该重新赋值 code 嘛?
代码 2 为修改后
Intellij idea 是个好东西
修改为:
catch 里面使用 printStackTrace(), 错误日志全部输出到 catalina.out, 你考虑过 catalina 的感受吗?
日志问题后面说
这是先斩后奏吗?前面都调用了 list 的 size 方法, 后面再来判断 list 是否为 null?
这种代码我看见起码不下 10 处, 系统能稳定吗老铁?
idea 都知道的问题, 你不应该不知道
logger.info 输出问题:
用 log.info("{}", xxxx), 不要自己拼接字符串
老铁, 你可长点心吧
老铁, 我就服你
google : logger.error() ...