SpringCloud配置碎碎念
SpringCloud配置信息部分解释如下:
eureka.instance.prefer-ip-address
1 | /** |
这段的意思是是否需要将serverName 转换为IP地址注册到eureka-server中。
两个例子:
1115 端口
1 | server: |
1116端口
1 | server: |
结果:1115端口转换为了IP地址注册,1116端口没有注册转换名称给服务器。
1 | [ |
SpringCloud配置信息部分解释如下:
1 | /** |
这段的意思是是否需要将serverName 转换为IP地址注册到eureka-server中。
两个例子:
1115 端口
1 | server: |
1116端口
1 | server: |
结果:1115端口转换为了IP地址注册,1116端口没有注册转换名称给服务器。
1 | [ |
Sharding-jdbc现在是Apache基金会顶级项目ShardingSphere下的一个产品,是以jdbc的形式支持读写分离、分库分表等类似数据库中间件功能,优点是入侵性小、配置方便,而且背后有个好爹。
Sharding-jdbc支持读写分离和分库分表两个核心功能,并且可以在读写分离基础上叠加分库分表。
Maven中央仓库中,有两个artifactId为sharding-jdbc的包,一个groupId是io.shardingjdbc,一个是org.apache.shardingsphere,注意不要选错了,apache的发布版本都是4.0.0之后的,之前的是老版本应该也不会继续更新了。
1 | <!-- https://mvnrepository.com/artifact/org.apache.shardingsphere/sharding-jdbc-core --> |
1 |
|
忽略druid的配置,使用读写分离的这版,druid的sql监控功能一直打不开。
之前线上系统并发量小,用单数据库实例节点就可以解决问题,最近压力有所上升,单节点经常遇到锁表的问题,数据库做过几次相关的优化还是老样子,就把数据库中间件的使用提上了日程。于是就开始了测试mycat的性能,做了几轮之后,性能还可以。但是忽略了一个重要的问题,测试都在单个schema下进行,今天偶然用到了跨库查询,结果就挂了。
mycat配置多个schema,只能在单个schema下进行查询,即便按照标准sql写出跨库查询sql,还是不会识别schema,只能在当前schenma下查询,即mysql的1064错误。
1 | <schema name="testdb1"> |
两个表都是不分片的表,但是位于不同的物理数据库上。也无法将某一批次的表做成全局表。即便做成全局表,也无法join成功。
支持单库内部任意join,支持跨库2表join,甚至基于caltlet的多表join。
官网给出的解释是支持跨库2表join,在应用已基本完成的情况下,不想再重新整理sql了。
替换方案是换成了apache的shardingsphere试试,看着介绍还不错
Nmap,也就是Network Mapper,最早是Linux下的网络扫描和嗅探工具包。
其基本功能有三个:
zennmap下载
下载后点击安装
1 | #ubuntu |
1 | [root@localhost ~]# nmap -T4 -A -v 192.168.1.25 |
1 | [root@localhost ~]# nmap -sn -PE -PA 192.168.1.0/24 |
基础的嗅探工作还挺好用
Druid作为阿里巴巴出品的数据库连接池产品,虽然从坊间传闻hikaricp性能更好,奈何Druid还有监控功能啊,线上的SQL问题统计方便很多,所以必须要了解下Druid的配置
以下对Druid的依赖管理略过。
StatViewServlet是一个标准的javax.servlet.http.HttpServlet,需要配置在你web应用中的WEB-INF/web.xml中。
1 | <servlet> |
根据配置中的url-pattern来访问内置监控页面,如果是上面的配置,内置监控页面的首页是/druid/index.html
打开上面的配置能够打开页面,相关的sql统计功能还需要打开统计功能:
1 | <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource" |
这样就可以查看到统计功能了。
一般JavaEE的工程具备一个contextPath,访问路径就是:http://ip:port/${contextPath}/druid/index.html
Spring Boot的配置更简单了,没有web.xml文件了,properties/yml的文件配置就够了。
1 | spring: |
就开启了druid的监控,但是这个有个问题,就是不认__server.serverlet.path__配置项。
如果用了shiro或者Spring-Security等权限管理,一定要关闭对druid的权限验证,而且也不推荐将druid合并到业务帐号里面。
有一台机器,已经建立了一个vg,容量是20T,现在准备新建一个lv,作为数据盘根目录,创建此LV过程中出现了各种的问题。
环境:
1 | centos 6.5 |
ext4分区理论可支持最大1EB,单文件体积16TB。但格式化的过程出现了:New size too large to be expressed in 32 bits 这个异常,晚上检索查找到,老版本的e2fsprogs命令存在16T的限制,此BUG修复要在E2fsprogs 1.42.12 (August 29, 2014)版本。
centos6.5默认是1.41,刚好错过一个版本,因为是甲方远程主机,更新出问题还要出差去修复,没敢做。
解决方案就是分成了两个10T的lv使用。
以下引自:理解inode
inode是什么?
理解inode,要从文件储存说起。
文件储存在硬盘上,硬盘的最小存储单位叫做”扇区”(Sector)。每个扇区储存512字节(相当于0.5KB)。
操作系统读取硬盘的时候,不会一个个扇区地读取,这样效率太低,而是一次性连续读取多个扇区,即一次性读取一个”块”(block)。这种由多个扇区组成的”块”,是文件存取的最小单位。”块”的大小,最常见的是4KB,即连续八个 sector组成一个 block。
文件数据都储存在”块”中,那么很显然,我们还必须找到一个地方储存文件的元信息,比如文件的创建者、文件的创建日期、文件的大小等等。这种储存文件元信息的区域就叫做inode,中文译名为”索引节点”。
每一个文件都有对应的inode,里面包含了与该文件有关的一些信息。
inode也需要占用一些存储空间,因为inode是预分配的,所以格式化的时候就已经确定inode的数量了。
每个inode节点的大小,一般是128字节或256字节。inode节点的总数,在格式化时就给定,一般是每1KB或每2KB就设置一个inode。假定在一块1GB的硬盘中,每个inode节点的大小为128字节,每1KB就设置一个inode,那么inode table的大小就会达到128MB,占整块硬盘的12.8%。
格式化时,每bytes-per-inode(或inode_ratio)字节大小的空间就创建一个inode,在分区大小固定前提下,该值越大,inode个数越少,data block就越多,该值越小,inode个数越多,data block就越少;以默认值16384(即16KiB)为例,如果文件系统上所有文件大小均为16KiB(或平均值),则data block耗尽的同时inode也将耗尽,二者占文件系统比例处于最理想状态,对于大量小文件的业务,通常将该值调小以增加inode数量;
1 | [defaults] |
通过更改inode_ratio的数值来控制inode的数量,用来控制inode的数量及空间,这部分影响格式化的速度。
如果是和上述相反的大文件存储业务,可以将inode_ratio值调大,以增加data block数量,如使用“-T largefile”选项对应的inode_ratio值为1MiB,在1.8TiB大小的分区创建ext4文件系统时,可增加20~30GiB左右的数据空间。
对于不能准备评估或需求特殊(如海量小文件)的存储业务,可考虑使用ReiserFS、XFS、JFS等,以避免inode耗尽的风险
第一份copy中git删除本地代码,完全重新初始化了代码,提交后,第二个copy使用正常的git pull 无法更新代码,需要进行强制删除操作。
1 | git fetch --all |
Mysql搭建主从其实配置特别简单,核心配置项目就那么几个就够了。
Master的配置项目
1 | [mysqld] |
其中只有server-id和log-bin这两项是最重要的,当然一般情况下会显示的指定binlog的格式,binlog日志文件的大小等配置。
Slave的配置:
1 | [mysqld] |
其中binlog-ignore-db和replicate-ignore-db分别在master和slave上面配置的不进行同步的数据库,建议两边完全对等,不要出现差异。
开启同步前要么保证主从状态一致,要么保证master的binlog足够slave同步到master一致的状态,不然Slave_sql_ruuning这个标识位会在某些时段变为NO,即便通过__set global sql_slave_skip_counter=1__设置将状态同步到一致,但数据极大可能仍然不是一致的,因为这个操作是跳过了master的部分操作。所以启动同步前一定要保证binlog足够,不然就手工同步一遍master到slave,再开启操作。
1 | mysql> show master status\G; |
从中提前两个结果 File和Position作为slave启动的脚本。
将master的file和position填入slave的启动语句中。
1 | stop slave; |
最后一个show slave status是为了确认是不是启动了额。监测指标核心是三个:Relay_Master_Log_File、Exec_Master_Log_Pos、Seconds_Behind_Master。前两个是核心指标,即slave读取到了master的binlog文件和位置,如果这两个参数的结果和master的binlog文件名称和postion一致,即可认为master和slave状态一致。SBM一定意义上表示了slave和master的时延是多少,这个时延是以slave的时间减去master的binlog时间戳,有作弊的可能,因此主要查看前两个参数。
启动应用,使用jmeter做压力测试,先将所有url都执行一遍,所有的select和insert类型的请求通过,包含update或者delete的请求失败,查看日志,报错信息:Connection is read-only. Queries leading to data modification are not allowed
select | insert | update | delete |
---|---|---|---|
o | o | x | x |
添加spring-boot的数据库链接池为非只读
1 | spring.datasource.druid.default-read-only=false |
select | insert | update | delete |
---|---|---|---|
o | o | x | x |
给所有涉及update或者delete的service类添加事务声明
1 | import org.springframework.transaction.annotation.Transactional; |
select | insert | update | delete |
---|---|---|---|
o | o | x | x |
select | insert | update | delete |
---|---|---|---|
o | o | o | o |
没有写入的问题,可以证明是mycat的连接的问题。
1 | <schema name="testdb" checkSQLschema="false" sqlMaxLimit="100"> |
1 | <user name="root" defaultAccount="true"> |
这部分生命信息看上去没有任何问题。
org.springframework.orm.jpa.vendor.HibernateJpaDialect.java beginTransaction方法
1 | @Override |
org.springframework.jdbc.datasource.DataSourceUtils.java Line:91
1 |
|
这个方法的解释是针对select方法,hibernate会强制设为只读请求,但为啥update方法会来这里,没有找到原因。
1 | spring.datasource.url=jdbc:log4jdbc:mysql://ip:8066/testdb?useUnicode=true&characterEncoding=utf-8&useLocalSessionState=true |
解决了这个问题,关于useLocalSessionState的解释是:__
默认情况下,我们的连接串信息没有包含useLocalSessionState参数的设置,这个值默认为false。
这个值的作用是驱动程序是否使用autocommit,read_only和transaction isolation的内部值(jdbc端的本地值)。
如果设置为false,则需要这个判断这三个参数的场景,都需要发语句到远端请求,比如更新语句前,
需要发语句select @@session.tx_read_only确认会话是否只读。
如果设置为true,则只需要取本地值即可。__
似乎是本地和远程服务器的配置有关,但远程服务器是mycat,莫非mycat的链接不是只读的,但没有找到mycat是只读的配置选项。
参数可以解决readOnly的问题,但只读链接的产生过程和原因不明。