关于Archetype介绍参考:Introduction to Archetypes
一、Archetype自定义流程:
1、创建模板工程:找到一个现有的项目,进行编辑,将项目中的包结构、各类文件放置到合适的位置;
2、从模板工程创建Archetype:打开cmd窗口,切换当前目录到上面的工程目录下,执行maven命令:
mvn archetype:create-from-project
执行完成后,target/generated-sourced/archetype目录下就是我们需要的项目模板。
3、安装Archetype到本地仓库:cd进入target/generated-sourced/archetype中,执行命令:
mvn -Dmaven.test.skip=true clean install
将自定义Archetype安装到本地仓库即可:此时,自定义archetype就被安装到settings.xml中<localRepository>指定的本地仓库中,我的机器本地目录是D:/q/repos-maven;另外,archetype安装到本地仓库后,会在.m2/archetype-catalog.xml中加入对应的archetype节点,结构如下:
<archetype>
<groupId>com.heckjj.blog</groupId>
<artifactId>crm-archetype-archetype</artifactId>
<version>1.0.0</version>
<description>The parent pom of crm</description>
</archetype>
4、使用自定义Archetype创建工程:
这样我们就创建成功了自定义的Archetype,可以通过命令从本地模板创建工程:
mvn archetype:generate -DarchetypeCatalog=local
以上就是创建自定义Archetype的简单流程。
比如对于策略模式,我们通常是定义一个接口,然后有不同的实现,这种是可以的,但是如果通用流程中要扩展的点较多的话,这些不同的实现也需要管理,可以把他们合并到一个单独的包中,再进一步,我们甚至可以将包单独提取出来,支持运行时加载包实现新增功能的支持
JDK对此功能的支持就是 SPI,但是它的限制较多,也不够灵活,比如dubbo就是自己定义了一套SPI的实现,这次我们来看另一个实现,pf4j 提供一套在基本框架中定义扩展点接口,然后通过不同的插件来实现扩展点的功能,来支持对新增开放对修改关闭
下面我们就来学习一下它的使用
使用
比如我们有一套通用的流程,假设是下单流程,不同的业务线等对于下单都有一些特殊点,但是它们的基本流程是相似的,这时候我们就可以先定义好通用的流程,不同的地方预留出扩展点接口,使用 pf4j 的流程如下
先定义好扩展点接口(需要定义单独的包,因为基本应用和各个扩展点的包都依赖它)
定义单独的插件包,其中实现扩展点接口的功能
在应用中编写基本流程和扩展点的发现使用功能
这次我们就参考 pf4j 提供的例子来看一下
1. 定义扩展点接口
pom.xml首先声明依赖
<dependency>
<groupId>org.pf4j</groupId>
<artifactId>pf4j</artifactId>
<version>3.6.0</version>
<!-- 一般应用中会依赖这个包,所以这里设置为provided即可 -->
<scope>provided</scope>
</dependency>
之后即可声明各个扩展点接口
/**
* 假设我们需要一个通知用户的功能
* 需要注意的是,我们一定要继承 ExtensionPoint 接口,表示这是一个扩展点
*/
public interface Notice extends ExtensionPoint {
boolean notice(List<Long> userIds);
}
本文例子基于Github地址:https://github.com/pf4j/pf4j
<dependency>
<groupId>org.pf4j</groupId>
<artifactId>pf4j</artifactId>
<version>3.6.0</version>
</dependency>
插件项目会涉及到3个工程:工程结构
plugin-api:定义可扩展接口
plugins:插件项目,可以包含多个插件,需要实现plugin-api中定义的接口
plugin-app:主程序,需要依赖plugin-api,加载并执行plugins
定义可扩展接口(plugin-api)
简单定义一个接口,需继承ExtensionPoint:
package plugin.api;
import org.pf4j.ExtensionPoint;
public interface Greeting extends ExtensionPoint {
String getGreeting();
}
实现插件(plugins)
插件需要实现plugin-api定义的接口,并且使用@Extension标记:
package plugins;
import org.pf4j.Extension;
import plugin.api.Greeting;
@Extension
public class WelcomeGreeting implements Greeting {
public String getGreeting() {
return "Welcome";
}
}
插件打包(plugins)
插件打包时,需要往MANIFEST.MF写入插件信息,此处使用maven插件(打包命令为package):
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.3.1</version>
<configuration>
<archive>
<manifestEntries>
<Plugin-Id>welcome-plugin</Plugin-Id>
<Plugin-Version>0.0.1</Plugin-Version>
</manifestEntries>
</archive>
</configuration>
</plugin>
1 连接数(Connects)
最大使用连接数:show status like ‘Max_used_connections’
当前打开的连接数:show status like ‘Threads_connected’
2 缓存(bufferCache)
未从缓冲池读取的次数:show status like ‘Innodb_buffer_pool_reads’
从缓冲池读取的次数:show status like ‘Innodb_buffer_pool_read_requests’
缓冲池的总页数:show status like ‘Innodb_buffer_pool_pages_total’
缓冲池空闲的页数:show status like ‘Innodb_buffer_pool_pages_free’
缓存命中率计算:(1-Innodb_buffer_pool_reads/Innodb_buffer_pool_read_requests)*100%
缓存池使用率为:((Innodb_buffer_pool_pages_total-Innodb_buffer_pool_pages_free)/Innodb_buffer_pool_pages_total)*100%
3 锁(lock)
锁等待个数:show status like ‘Innodb_row_lock_waits’
平均每次锁等待时间:show status like ‘Innodb_row_lock_time_avg’
查看是否存在表锁:show open TABLES where in_use>0;有数据代表存在锁表,空为无表锁
4 SQL
查看 mysql 开关是否打开:show variables like ‘slow_query_log’,ON 为开启状态,如果为 OFF,set global slow_query_log=1 进行开启
查看 mysql 阈值:show variables like ‘long_query_time’,根据页面传递阈值参数,修改阈值 set global long_query_time=0.1
查看 mysql 慢 sql 目录:show variables like ‘slow_query_log_file’
格式化慢 sql 日志:mysqldumpslow -s at -t 10 /export/data/mysql/log/slow.log
注:此语句通过 jdbc 执行不了,属于命令行执行。
意思为:显示出耗时最长的 10 个 SQL 语句执行信息,10 可以修改为 TOP 个数。显示的信息为:执行次数、平均执行时间、SQL 语句
5 statement
insert 数量:show status like ‘Com_insert’
delete 数量:show status like ‘Com_delete’
update 数量:show status like ‘Com_update’
select 数量:show status like ‘Com_select’
6 吞吐(Database throughputs)
发送吞吐量:show status like ‘Bytes_sent’
接收吞吐量:show status like ‘Bytes_received’
总吞吐量:Bytes_sent+Bytes_received
7 数据库参数(serverconfig)
show variables8 慢 SQL
慢 SQL 指的是 MySQL 慢查询,具体指运行时间超过 long_query_time 值的 SQL。我们常听 MySQL 中有二进制日志 binlog、中继日志 relaylog、重做回滚日志 redolog、undolog 等。针对慢查询,还有一种慢查询日志 slowlog,用来记录在 MySQL 中响应时间超过阀值的语句。慢 SQL 对实际生产业务影响是致命的,所以测试人员在性能测试过程中,对数据库 SQL 语句执行情况实施监控,给开发提供准确的性能优化意见显得尤为重要。那怎么使用 Mysql 数据库提供的慢查询日志来监控 SQL 语句执行情况,找到消耗较高的 SQL 语句,以下详细说明一下慢查询日志的使用步骤:
确保打开慢 SQL 开关 slow_query_log
设置慢 SQL 域值 long_query_time
这个 long_query_time 是用来定义慢于多少秒的才算 “慢查询”,注意单位是秒,我通过执行 sql 指令 set long_query_time=1 来设置了 long_query_time 的值为 1, 也就是执行时间超过 1 秒的都算慢查询。
查看慢 SQL 日志路径
通过慢 sql 分析工具 mysqldumpslow 格式化分析慢 SQL 日志
mysqldumpslow 慢查询分析工具,是 mysql 安装后自带的,可以通过./mysqldumpslow —help 查看使用参数说明
取出使用最多的 10 条慢查询
./mysqldumpslow -s c -t 10 /export/data/mysql/log/slow.log取出查询时间最慢的 3 条慢查询
./mysqldumpslow -s t -t 3 /export/data/mysql/log/slow.log
假如: SELECT FROM sms_send WHERE service_id=10 GROUP BY content LIMIT 0, 1000;
mysqldumpslow 命令执行后显示:
Count: 2 Time=1.5s (3s) Lock=0.00s (0s) Rows=1000.0 (2000), vgos_dba[vgos_dba]@[10.130.229.196]SELECT FROM sms_send WHERE service_id=N GROUP BY content LIMIT N, Nmysqldumpslow 的分析结果详解:
Count:表示该类型的语句执行次数,上图中表示 select 语句执行了 2 次。
Time:表示该类型的语句执行的平均时间(总计时间)
Lock:锁时间 0s。
Rows:单次返回的结果数是 1000 条记录,2 次总共返回 2000 条记录。
不使用子查询
SELECT FROM t1 WHERE id (SELECT id FROM t2 WHERE name=’hechunyang’);
子查询在 MySQL5.5 版本里,内部执行计划器是这样执行的:先查外表再匹配内表,而不是先查内表 t2,当外表的数据很大时,查询速度会非常慢。
在 MariaDB10/MySQL5.6 版本里,采用 join 关联方式对其进行了优化,这条 SQL 会自动转换为 SELECT t1. FROM t1 JOIN t2 ON t1.id = t2.id;
但请注意的是:优化只针对 SELECT 有效,对 UPDATE/DELETE 子 查询无效, 生产环境尽量应避免使用子查询。避免函数索引
SELECT FROM t WHERE YEAR(d) >= 2016;
由于 MySQL 不像 Oracle 那样⽀持函数索引,即使 d 字段有索引,也会直接全表扫描。
应改为 > SELECT FROM t WHERE d >= ‘2016-01-01’;用 IN 来替换 OR 低效查询
慢 SELECT FROM t WHERE LOC_ID = 10 OR LOC_ID = 20 OR LOC_ID = 30;
高效查询 > SELECT FROM t WHERE LOC_IN IN (10,20,30);LIKE 双百分号无法使用到索引
SELECT FROM t WHERE name LIKE ‘%de%’;
使用 SELECT FROM t WHERE name LIKE ‘de%’;分组统计可以禁止排序
SELECT goods_id,count() FROM t GROUP BY goods_id;
默认情况下,MySQL 对所有 GROUP BY col1,col2… 的字段进⾏排序。如果查询包括 GROUP BY,想要避免排序结果的消耗,则可以指定 ORDER BY NULL 禁止排序。
使用 SELECT goods_id,count () FROM t GROUP BY goods_id ORDER BY NULL;禁止不必要的 ORDER BY 排序
SELECT count(1) FROM user u LEFT JOIN user_info i ON u.id = i.user_id WHERE 1 = 1 ORDER BY u.create_time DESC;
使用 SELECT count (1) FROM user u LEFT JOIN user_info i ON u.id = i.user_id;
9 总结
任何东西不应过重关注其外表,要注重内在的东西,往往绚丽的外表下会有对应的负担和损耗。
mysql 数据库的监控支持通过 SQL 方式从 performance_schema 库中访问对应的表数据,前提是初始化此库并开启监控数据写入。
对于监控而言,不在于手段的多样性,而需要明白监控的本质,以及需要的监控项内容,找到符合自身项目特色的监控方式。
在选择监控工具对 mysql 监控时,需要关注监控工具本身对于数据库服务器的消耗,不要影响到其自身的使用。
报错原因为配置中找不到一个指定自动注入类型的bean。
那么我们要从collecter层开始查找,点击service层,看service实现类是否加上@Service或者@Component,检查service实现类是否有implements service。如果这些都没有问题:
我们来看@SpringBootApplication,点过去。可以看到有个@ComponentScan,ComponentScan做的事情就是告诉Spring从哪里找到bean
那可以直接在@SpringBootApplication加上
还有一种问题,你的spring启动类不在同一个父包路径下,比如你的其它类在com.heckjj.blog,而你的启动类在heckjj下,也会报错扫不到其它的类,比如说service找不到。
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<version>3.0.2</version>
<configuration>
<encoding>UTF-8</encoding>
<nonFilteredFileExtensions>
<nonFilteredFileExtension>xls</nonFilteredFileExtension>
<nonFilteredFileExtension>xlsx</nonFilteredFileExtension>
</nonFilteredFileExtensions>
</configuration>
</plugin>
问题产生的原因:
由于我远程的Oracle是 11g的,但是Navicat本身的Oracle oci.dll文件是10g的,数据库与链接库的版本不一致,所以会报错。
打开navicat的安装目录,查看有没有以下文件:
解决方案:
1、我们去Oracle官网下载对应的Instant Client Package -Version 11.2.0.4.0 - Basic的文件即可
下载地址:Instant Client for Microsoft Windows (x64) 64-bit
或者自行网上搜索下载
下载好之后,解压到navicat安装目录下
2、启动navicat客户端 找到【工具】->【选项】->【环境】
将OCI环境更改为11_2下的oci.dll即可,重启之后即可生效!
中文文档:https://www.npmjs.cn/
(1)不用单独安装,它随 node 一起提供,node装好了npm就自动装好了【node是一个JS运行环境】
(2)npm是一个包,这个包可以管理(下载、更新、删除)别的包
(3)npm在下载包的时候有一个缓存的过程,我们一般不会使用npm默认下载缓存目录,而会自定义指定npm下载缓存目录
执行 npm config set cache "C:\Program Files\nodejs\npm_cache"
(4)npm下载包分为本地下载和全局下载,本地下载会下载到指定的文件夹,而全局下载会下载到默认的全局包保存路径,我们一般不会使用npm默认的全局包下载保存路径,而会自定义指定npm全局包下载路径。
执行 npm config set prefix "C:\Program Files\nodejs\npm_global"
(5)npm install的时候巨慢。特别是新的项目拉下来要等半天,删除node_modules,重新install的时候依旧如此。
(6)同一个项目,安装的时候无法保持一致性。由于package.json文件中版本号的特点,下面三个版本号在安装的时候代表不同的含义。 “5.0.3”表示安装指定的5.0.3版本,“~5.0.3”表示安装5.0.X中最新的版本,“^5.0.3”表示安装5.X.X中最新的版本。这就麻烦了,常常会出现同一个项目,有的同事是OK的,有的同事会由于安装的版本不一致出现bug。
"5.0.3",
"~5.0.3",
"^5.0.3"
(7)安装的时候,包会在同一时间下载和安装,中途某个时候,一个包抛出了一个错误,但是npm会继续下载和安装包。因为npm会把所有的日志输出到终端,有关错误包的错误信息就会在一大堆npm打印的警告中丢失掉,并且你甚至永远不会注意到实际发生的错误。
在使用beanutils工具类封装javabean时,beanUtils不提供直接将字符串转换成Date(java.util.Date)数据类型的方法,所以会出现下面警告:
在控制层中写入以下代码
DateConverter converter = new DateConverter();
converter.setPattern(new String("yyyy-MM-dd"));
ConvertUtils.register(converter, Date.class);
https://tts.baidu.com/text2audio?tex=一瞬间的决定,往往可以改变很多,事实上,让自己成功的往往不是知识,是精神! 如果你总是为自己找借口,那只好让成功推迟。执行力,今天!&cuid=heck&cod=2&lan=zh&ctp=1&pdt=301&spd=5&per=0&vol=5&pit=5
https://fanyi.sogou.com/reventondc/synthesis?text=Heck%27s%20blog,一瞬间的决定,往往可以改变很多,事实上,让自己成功的往往不是知识,是精神! 如果你总是为自己找借口,那只好让成功推迟。执行力,今天!&speed=1&speaker=6
https://fanyi.baidu.com/gettts?lan=zh&text=一瞬间的决定,往往可以改变很多,事实上,让自己成功的往往不是知识,是精神! 如果你总是为自己找借口,那只好让成功推迟。执行力,今天!&spd=5&source=web
https://tts.youdao.com/fanyivoice?word=一瞬间的决定,往往可以改变很多,事实上,让自己成功的往往不是知识,是精神! 如果你总是为自己找借口,那只好让成功推迟。执行力,今天!&le=zh&keyfrom=speaker-target
https://api.microsofttranslator.com/V2/Http.svc/Speak?language=zh-CHS&appid=05DBC69E5594C137B9E22680F92F8E5E115A7817&text=一瞬间的决定,往往可以改变很多,事实上,让自己成功的往往不是知识,是精神! 如果你总是为自己找借口,那只好让成功推迟。执行力,今天!&format=audio/mp3&options=MaxQuality