非常感谢「后端圈」小伙伴们的高质量技术交流。 这里,我使用「知识星球」沉淀「2018年的第23周」高质量的答疑内容。本周与你一起精进 8 个问题,请细心阅读。如果对您有帮助的话,可以帮忙转发与分享。同时,欢迎加入「后端群」与「知识星球」共同探讨,一起进步,文末扫描关注,或公众号回复「加群」。
问题1:网络状态中[::]和[::1]的含义
[上海-Java-小白] 提问:
这里的[::]和[::1]是什么意思?
问题解答:
**[龙童幽灵] **是IPv6的缩写码,连续的0进行了缩写。[::]代表地址全是0;[::1]代表只有最后一位是1,其他都是0。注意一个地址只能缩写一次,比如:0.0.0.0.1.0.0.0.1 只能缩写成 [::1.0.0.0.1],即一个IPv6的IP地址里只能有一个缩写。
问题2:缓存与冷/热数据
**[北京-java-Waters] **提问:
我们生产没用redis存热数据,如果我要存热数据的话,是需要改造DAO层方法么?改造成:先查缓存,再查数据库么?
问题解答:
[龙童幽灵] 只需要改造DAO,查询方法判断是否返回null,是的话就是没数据,然后去查数据库 ,这个就是所谓的穿透缓存。
**[知秋] **服务层做的事情,不要放在dao层,内存依然是有限的,不是什么冷数据都需要存的,而且存储冷数据本身就是在浪费性能,降低热点数据的效率 。对于cache,也可以使用同一个注解进行n套缓存api的操作实现,中间使用一个策略判断即可,碰到新版本的缓存或者比较好用的操作api可以自己试着拓展封装一下的。
**[贺卓凡@ImportSource] **cache统一封装,支持多种缓存接入,ehcache、内存 map,甚至自定义cache,比如redis等 。支持注解方式和autowired方式get到具体的缓存连接,比如jedis
问题3:如何移除某个模块的某个包或class
[北京-Java-眼眼] 提问:
maven有办法移除某个模块下的某个包或者class吗?公司框架统一扫描的路径下有2个重名类导致报错,2个类的在不同jar包,但是2个类的类名和包路径相同。但是公司肯定不让改jar包,会影响别人调用 。
问题解答:
[深圳-Java-阿飞] 这个不可以吧,这是类加载机制的问题,只要类路径下的jar包,类加载机制就可以加载它。
**[石家庄-后端-刘增辉] **用maven-shade插件,把有冲突的jar,合并到要发布的jar中。 maven-shade能改包名,不会和原有版本的冲突 。
问题4:对象之间数据复制
**[北京-Java-眼眼] **提问:
两个不同类型的对象,有部分属性相同,如何能同步相同属性的值?
问题解答:
[杭州-后端-梁桂钊] Apache BeanUtils 性能较差,可以使用其他方案。比如 Spring BeanUtils。事实上,Apache 的 BeanUtils.copyProperties 第一次调用 get 会初始化执行,并且缓存对象。但是,为了保证线程安全使用了 synchronized,因此不同线程第一次调用执行,框架需要先初始化,并且并发访问同一个实例时会出现线程阻塞。此外,注意的是,Apache BeanUtils 和 Spring BeanUtils 参数顺序是不一致的哟,其本质都是反射。此外,还可以考虑另外一种方式,就是运行的时候编译,例如 mapstruct。
问题5:Dubbo 启动异常
**[小林] **提问:
我使用 maven-assembly-plugin 插件打包成 tar 文件,上传服务器,用脚本启动的服务。请问 dubbo 启动脚本中这段代码是什么意思?我的理解是 :搜索当前目录下是否存在 java 进程,存在则报服务已经启动,就一直报这个错误。
问题解答:
**[兰小伟-《Solr权威指南》] **它是根据pid文件来判断,可能pid文件由于异常导致删除失败,下次启动发现pid文件还在,脚本就认为进程还在 。删除pid文件或者把文件里的进程id内容删除就行,你查下脚本里的CONF_DIR路径是啥 ,顺着这个路径去找那个文件。也可以手动执行下PIDS表示的那个命令,看看返回什么。或者手动把进程杀掉,ps -f看下哪个进程在占用CONF_DIR指代的目录 。
问题6:MySQL 模糊查询查询效率最快
**[北京-后端-马金路] **提问:
MySQL 中某个字段的模糊查询,在数据量较大的情况下,什么方式查询效率最大?
问题解答:
**[杭州-后端-梁桂钊] **like 的方式进行查询,在 like “value%” 可以使用索引,但是对于 like “%value%” 这样的方式,执行全表查询,对于海量数据,全表扫描是非常可怕的事情。简单对我情况下,可以使用全文搜索的方式进行优化。全文搜索在 MySQL 中是一个 FULLTEXT 类型索引。 FULLTEXT 索引在 MySQL 5.6 版本之后支持 InnoDB,而之前的版本只支持 MyISAM 表。更好的做法,根据业务需求,考虑使用 ElasticSearch 或 Solr 是个不错的方案。
问题7:MySQL 全文索引不支持中文
[广州-PHP-anker] 提问:
MySQL 全文索引不支持中文,如何解决?
问题解答:
[杭州-后端-梁桂钊] 默认 MySQL 不支持中文全文检索,对此,网上的方案很多,例如添加 MySQL 扩展,或者将内容转换成拼音的方式存储在索引表,或者使用 IKAnalyzer 分词库等,其效果都不是非常的理想。使用拼音分词,虽然可以查询到内容,但是如果拼音相同的情况,是非常致命的,而且分词的粒度也是个很可怕的问题。这里,使用 IKAnalyzer 分词库,是一个不错的选择。但是,因为业务的需要,命中率也是非常重要的,有的关键字没有进行分词导致查询不到的问题。我之前的临时解决方案。如下:为中文内容表提供一个全文索引表,存储全文索引分词信息,两张表根据中文内容表的 ID 进行关联。将内容进行分词后,用 base64 编码,保存在全文索引表中。关键的一步,如何分词,分词的命中率问题。很简单,自定义分词库,写一个分词算法将所有的组合进行分词,在内容不多的情况下非常有用。举个例子,“梁桂钊”,可以进行自定义分词:[梁、桂、钊、梁桂、桂钊、梁桂钊]。事实上,MySQL 全文搜索只是一个临时方案,对于全文搜索场景,更专业的做法是使用全文搜索引擎,例如 ElasticSearch 或 Solr。
问题8:消息推送的设计
**[重庆-后端-阿童木] **提问:
系统中一个模块,默认每个用户可配置数种通知类型,假设 10 种,按一定的业务规则,定时从某些业务数据表中抓取数据,根据模板生成消息记录,然后调用对应的接口进行发送,比如短信接口,邮件接口。目前保守估计当前用户量为 2 万,每种通知类型 1 天 100 条通知,算下来,QPS 约为 231。上线后用户量增长率无法预估,但是可以确定的是量级肯定会发生较大变化,对应的 QPS 变化也较大,目前考虑 MQ,对以后业务量的变化会比较有保障. 另外,消息时效性要求不是特别高,可靠性是最重要的要求。
问题解答:
**[杭州-后端-梁桂钊] **上线后用户量增长率无法预估,但是可以确定的是量级肯定会发生较大变化。这种情况下,从三个层面考虑。首先,MQ做一层缓冲区,可以起到消峰的作用。生产者去推任务,消费者取到模版加工推渠道(短信,邮件,各种端)。然后,数据库考虑分库分布,肯定要落地触达日志的。最后,限流方案。评估目前业务量,添加限流机制。如果,考虑技术成本问题,以及团队积累问题?,可以考虑阻塞队列 + 线程池 + 数据库过渡。先写数据库,在写队列。数据库做一层持久化,然后监控数据库的消费状态。加一层限流来解决消峰问题。另外需考虑数据库容量增长问题,可按时间提前分表。