12月7
一、前言
MySQL 支持由 RFC 7159 定义的原生JSON 数据类型,该数据类型可以有效访问 JSON(JavaScript Object Notation)中的元素数据。与将JSON 格式的字符串存储为单个字符串类型相比,JSON 数据类型具有以下优势:
自动验证存储在JSON列中的JSON数据格式。无效格式会报错。
优化的存储格式。存储在JSON列中的JSON文档被转换为允许快速读取访问文档元素的内部格式。内部是以二进制格式存储JSON数据。
对JSON文档元素的快速读取访问。当服务器读取JSON文档时,不需要重新解析文本获取该值。通过key或数组索引直接查找子对象或嵌套值,而不需要读取整个JSON文档。
存储JSON文档所需的空间,大致与LONGBLOB或LONGTEXT相同
存储在JSON列中的任何JSON文档的大小都仅限于设置的系统变量max_allowed_packet的值
MySQL 8.0.13之前,JSON列不能有非null的默认值。
在 MySQL 8.0 中,优化器可以对 JSON 列执行部分就地更新,而不是删除旧JSON串并将新串完整地写入列。
MYSQL 8.0,除了提供JSON 数据类型,还有一组 SQL 函数可用于操作 JSON 的值,例如创建JSON对象、增删改查JSON数据中的某个元素。
二、常用JSON函数
首先,创建表列时候,列要设置为JSON类型:
1
CREATE TABLE t1 (content JSON);
插入数据,可以像插入varchar类型的数据一样,把json串添加单引号进行插入:
1
INSERT INTO t1 VALUES('{"key1": "value1", "key2": "value2"}');
当然mysql也提供了创建JSON对象的函数:
1
INSERT INTO t1 VALUES(JSON_OBJECT("key1","value1","key2","value2"));
使用JSON_EXTRACT函数查询JSON类型数据中某个元素的值:
mysql> SELECT JSON_EXTRACT(content,"$.key1") from t1;
+--------------------------------+
| JSON_EXTRACT(content,"$.key1") |
+--------------------------------+
| "value1" |
| "value1" |
+--------------------------------+
2 rows in set (0.00 sec)
lamba表达式风格查询:
mysql> SELECT content->"$.key1" from t1;
+-------------------+
| content->"$.key1" |
+-------------------+
| "value1" |
| "value1" |
+-------------------+
2 rows in set (0.00 sec)
使用JSON_SET函数更新JSON中某个元素的值,如果不存在则添加:
mysql> update t1 set content=JSON_SET(content,"$.key1",'value111');
Query OK, 2 rows affected (0.00 sec)
Rows matched: 2 Changed: 2 Warnings: 0
更多JSON类型数据操作函数,可以参考:https://dev.mysql.com/doc/refman/8.0/en/json.html
三、MyBatis中使用JSON类型及其操作函数
比如Device表里面有个JSON类型的content字段,其中含有名称为name的元素,我们来修改和查询name元素对应的值。
ExtMapper中定义修改和查询接口:
@Mapper
public interface DeviceDOExtMapper extends com.zlx.user.dal.mapper.DeviceDOMapper {
//更新JSON串中名称为name的key的值
int updateName(@Param("name") String name, @Param("query") DeviceQuery query);
//查询JSON串中名称为name的key的值
String selectName(DeviceQuery query);
}
ExtMapper.xml中定义查询sql:
<mapper namespace="com.zlx.user.dal.mapper.ext.DeviceDOExtMapper">
<!--更新JSON串中名称为name的key的值-->
<update id="updateName" parameterType="map">
update device
<set>
<if test="name != null">
content = JSON_SET(content, '$.name', #{name,jdbcType=VARCHAR})
</if>
</set>
<if test="_parameter != null">
<include refid="Update_By_Example_Where_Clause"/>
</if>
</update>
<!--查询JSON串中名称为name的key的值-->
<select id="selectName" parameterType="com.zlx.user.dal.model.DeviceQuery" resultType="java.lang.String">
select
`content`->'$.name'
from device
<if test="_parameter != null">
<include refid="Example_Where_Clause"/>
</if>
</select>
</mapper>
总结
虽然我们实践上不建议把所有扩展字段都放到一个大字段里面。但是即使有原因一定到放,那么也建议选择JSON类型,而不是varcahr和Text类型。
参考:
https://dev.mysql.com/doc/refman/8.0/en/json.html
MySQL 支持由 RFC 7159 定义的原生JSON 数据类型,该数据类型可以有效访问 JSON(JavaScript Object Notation)中的元素数据。与将JSON 格式的字符串存储为单个字符串类型相比,JSON 数据类型具有以下优势:
自动验证存储在JSON列中的JSON数据格式。无效格式会报错。
优化的存储格式。存储在JSON列中的JSON文档被转换为允许快速读取访问文档元素的内部格式。内部是以二进制格式存储JSON数据。
对JSON文档元素的快速读取访问。当服务器读取JSON文档时,不需要重新解析文本获取该值。通过key或数组索引直接查找子对象或嵌套值,而不需要读取整个JSON文档。
存储JSON文档所需的空间,大致与LONGBLOB或LONGTEXT相同
存储在JSON列中的任何JSON文档的大小都仅限于设置的系统变量max_allowed_packet的值
MySQL 8.0.13之前,JSON列不能有非null的默认值。
在 MySQL 8.0 中,优化器可以对 JSON 列执行部分就地更新,而不是删除旧JSON串并将新串完整地写入列。
MYSQL 8.0,除了提供JSON 数据类型,还有一组 SQL 函数可用于操作 JSON 的值,例如创建JSON对象、增删改查JSON数据中的某个元素。
二、常用JSON函数
首先,创建表列时候,列要设置为JSON类型:
1
CREATE TABLE t1 (content JSON);
插入数据,可以像插入varchar类型的数据一样,把json串添加单引号进行插入:
1
INSERT INTO t1 VALUES('{"key1": "value1", "key2": "value2"}');
当然mysql也提供了创建JSON对象的函数:
1
INSERT INTO t1 VALUES(JSON_OBJECT("key1","value1","key2","value2"));
使用JSON_EXTRACT函数查询JSON类型数据中某个元素的值:
mysql> SELECT JSON_EXTRACT(content,"$.key1") from t1;
+--------------------------------+
| JSON_EXTRACT(content,"$.key1") |
+--------------------------------+
| "value1" |
| "value1" |
+--------------------------------+
2 rows in set (0.00 sec)
lamba表达式风格查询:
mysql> SELECT content->"$.key1" from t1;
+-------------------+
| content->"$.key1" |
+-------------------+
| "value1" |
| "value1" |
+-------------------+
2 rows in set (0.00 sec)
使用JSON_SET函数更新JSON中某个元素的值,如果不存在则添加:
mysql> update t1 set content=JSON_SET(content,"$.key1",'value111');
Query OK, 2 rows affected (0.00 sec)
Rows matched: 2 Changed: 2 Warnings: 0
更多JSON类型数据操作函数,可以参考:https://dev.mysql.com/doc/refman/8.0/en/json.html
三、MyBatis中使用JSON类型及其操作函数
比如Device表里面有个JSON类型的content字段,其中含有名称为name的元素,我们来修改和查询name元素对应的值。
ExtMapper中定义修改和查询接口:
@Mapper
public interface DeviceDOExtMapper extends com.zlx.user.dal.mapper.DeviceDOMapper {
//更新JSON串中名称为name的key的值
int updateName(@Param("name") String name, @Param("query") DeviceQuery query);
//查询JSON串中名称为name的key的值
String selectName(DeviceQuery query);
}
ExtMapper.xml中定义查询sql:
<mapper namespace="com.zlx.user.dal.mapper.ext.DeviceDOExtMapper">
<!--更新JSON串中名称为name的key的值-->
<update id="updateName" parameterType="map">
update device
<set>
<if test="name != null">
content = JSON_SET(content, '$.name', #{name,jdbcType=VARCHAR})
</if>
</set>
<if test="_parameter != null">
<include refid="Update_By_Example_Where_Clause"/>
</if>
</update>
<!--查询JSON串中名称为name的key的值-->
<select id="selectName" parameterType="com.zlx.user.dal.model.DeviceQuery" resultType="java.lang.String">
select
`content`->'$.name'
from device
<if test="_parameter != null">
<include refid="Example_Where_Clause"/>
</if>
</select>
</mapper>
总结
虽然我们实践上不建议把所有扩展字段都放到一个大字段里面。但是即使有原因一定到放,那么也建议选择JSON类型,而不是varcahr和Text类型。
参考:
https://dev.mysql.com/doc/refman/8.0/en/json.html
12月6
var userAgent=navigator.userAgent
if(userAgent.index0f("OPR")> -1){
//0pera浏览器,因为Opera浏览器的userAgent也有Chrome和Safari,所以要写在前面 alert("Opera");
}else if(userAgent.index0f("Version")>-1&&userAgent.index0f("Safari")> -1){
//没有更好的办法判断Safari浏览器,只能通过version(版本号)的英又来断,因为别的游览器版本号不是这样写的 alert("Safari"):
}else if(userAgent.index0f("Chrome")> -1){
//谷歌浏览器也有可能是使朋Chrome内核的其他谢览器 alert("Chrome");
}else if(userAgent.index0f("Firefox")>-1){
//火狐浏览器
alert("Firefox");
}else if(userAgent.index0f("compatible")>-1 &&userAgent.index0f("MSIE 10.0")> -1){
//IE 10.0
alert("IE 10.0");
}else if(userAgent.index0f("compatible")>-1&& userAgent.index0f("MSIE 9.0")> -1){
//IE 9.0
alert("IE 9.0");
}else if(userAgent.index0f("compatible")>-1 &&userAgent.index0f("MSIE 8.0")> -1){
//IE 8.0
alert("IE 8.0");
helse if(userAgent.index0f("compatible")>-1&& userAgent.index0f("MSIE 7.0")> -1){
//IE 7.0
alert("IE 7.0");
各浏览器的navigator.userAgent
浏览器 navigator.userAgent
谷歌 Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/57.0.2987.133 Safari/537.36
火狐 Mozilla/5.0 (Windows NT 10.0; WOW64; rv:53.0) Gecko/20100101 Firefox/53.0
Opera Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.81 Safari/537.36 OPR/45.0.2552.635
Safari Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/603.1.30 (KHTML, like Gecko) Version/10.1 Safari/603.1.30
IE11.0 Mozilla/5.0 (Windows NT 10.0; WOW64; Trident/7.0; .NET4.0C; .NET4.0E; .NET CLR 2.0.50727; .NET CLR 3.0.30729; .NET CLR 3.5.30729; rv:11.0) like Gecko
IE10.0 Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 10.0; WOW64; Trident/7.0; .NET4.0C; .NET4.0E; .NET CLR 2.0.50727; .NET CLR 3.0.30729; .NET CLR 3.5.30729)
IE9.0 Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 10.0; WOW64; Trident/7.0; .NET4.0C; .NET4.0E; .NET CLR 2.0.50727; .NET CLR 3.0.30729; .NET CLR 3.5.30729)
IE8.0 Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 10.0; WOW64; Trident/7.0; .NET4.0C; .NET4.0E; .NET CLR 2.0.50727; .NET CLR 3.0.30729; .NET CLR 3.5.30729)
IE7.0 Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 10.0; WOW64; Trident/7.0; .NET4.0C; .NET4.0E; .NET CLR 2.0.50727; .NET CLR 3.0.30729; .NET CLR 3.5.30729)
Windows NT 区别系统版本
系统版本 Windows NT
win 10 Windows NT 10.0
win 8 Windows NT 6.2
win 7 Windows NT 6.1
vista Windows NT 6.0
win xp Windows NT 5.1
win 2000 Windows NT 5.0
if(userAgent.index0f("OPR")> -1){
//0pera浏览器,因为Opera浏览器的userAgent也有Chrome和Safari,所以要写在前面 alert("Opera");
}else if(userAgent.index0f("Version")>-1&&userAgent.index0f("Safari")> -1){
//没有更好的办法判断Safari浏览器,只能通过version(版本号)的英又来断,因为别的游览器版本号不是这样写的 alert("Safari"):
}else if(userAgent.index0f("Chrome")> -1){
//谷歌浏览器也有可能是使朋Chrome内核的其他谢览器 alert("Chrome");
}else if(userAgent.index0f("Firefox")>-1){
//火狐浏览器
alert("Firefox");
}else if(userAgent.index0f("compatible")>-1 &&userAgent.index0f("MSIE 10.0")> -1){
//IE 10.0
alert("IE 10.0");
}else if(userAgent.index0f("compatible")>-1&& userAgent.index0f("MSIE 9.0")> -1){
//IE 9.0
alert("IE 9.0");
}else if(userAgent.index0f("compatible")>-1 &&userAgent.index0f("MSIE 8.0")> -1){
//IE 8.0
alert("IE 8.0");
helse if(userAgent.index0f("compatible")>-1&& userAgent.index0f("MSIE 7.0")> -1){
//IE 7.0
alert("IE 7.0");
各浏览器的navigator.userAgent
浏览器 navigator.userAgent
谷歌 Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/57.0.2987.133 Safari/537.36
火狐 Mozilla/5.0 (Windows NT 10.0; WOW64; rv:53.0) Gecko/20100101 Firefox/53.0
Opera Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.81 Safari/537.36 OPR/45.0.2552.635
Safari Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/603.1.30 (KHTML, like Gecko) Version/10.1 Safari/603.1.30
IE11.0 Mozilla/5.0 (Windows NT 10.0; WOW64; Trident/7.0; .NET4.0C; .NET4.0E; .NET CLR 2.0.50727; .NET CLR 3.0.30729; .NET CLR 3.5.30729; rv:11.0) like Gecko
IE10.0 Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 10.0; WOW64; Trident/7.0; .NET4.0C; .NET4.0E; .NET CLR 2.0.50727; .NET CLR 3.0.30729; .NET CLR 3.5.30729)
IE9.0 Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 10.0; WOW64; Trident/7.0; .NET4.0C; .NET4.0E; .NET CLR 2.0.50727; .NET CLR 3.0.30729; .NET CLR 3.5.30729)
IE8.0 Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 10.0; WOW64; Trident/7.0; .NET4.0C; .NET4.0E; .NET CLR 2.0.50727; .NET CLR 3.0.30729; .NET CLR 3.5.30729)
IE7.0 Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 10.0; WOW64; Trident/7.0; .NET4.0C; .NET4.0E; .NET CLR 2.0.50727; .NET CLR 3.0.30729; .NET CLR 3.5.30729)
Windows NT 区别系统版本
系统版本 Windows NT
win 10 Windows NT 10.0
win 8 Windows NT 6.2
win 7 Windows NT 6.1
vista Windows NT 6.0
win xp Windows NT 5.1
win 2000 Windows NT 5.0
12月6
报错信息:
java.io.IOException: No space left on deviceat java.io.FileOutputStream.writeBytes(Native Method)at java.io.FileOutputStream.write(FileOutputStream.java:282)at sun.nio.cs.StreamEncoder.writeBytes(StreamEncoder.java:202)at sun.nio.cs.StreamEncoder.implFlushBuffer(StreamEncoder.java:272)at sun.nio.cs.StreamEncoder.implFlush(StreamEncoder.java:276)at sun.nio.cs.StreamEncoder.flush(StreamEncoder.java:122)at java.io.OutputStreamWriter.flush(OutputStreamWriter.java:212)
服务器磁盘不足,df -h 一下,发现tmpfs挂载的tmp文件夹只有2M剩下的只有几K了,在想应该是这个问题,于是将tmp目录调大一点,下面调到2g,输入以下命令:
mount -t tmpfs -o size=2g tmpfs /tmp
重新上传文件,发现成功上传,问题解决。
java.io.IOException: No space left on deviceat java.io.FileOutputStream.writeBytes(Native Method)at java.io.FileOutputStream.write(FileOutputStream.java:282)at sun.nio.cs.StreamEncoder.writeBytes(StreamEncoder.java:202)at sun.nio.cs.StreamEncoder.implFlushBuffer(StreamEncoder.java:272)at sun.nio.cs.StreamEncoder.implFlush(StreamEncoder.java:276)at sun.nio.cs.StreamEncoder.flush(StreamEncoder.java:122)at java.io.OutputStreamWriter.flush(OutputStreamWriter.java:212)
服务器磁盘不足,df -h 一下,发现tmpfs挂载的tmp文件夹只有2M剩下的只有几K了,在想应该是这个问题,于是将tmp目录调大一点,下面调到2g,输入以下命令:
mount -t tmpfs -o size=2g tmpfs /tmp
重新上传文件,发现成功上传,问题解决。
12月1
目录结构: tomcat/logs目录.
1.实时查看当前项目的运行日志,进入logs目录,
tail -f catalina.out
扩展: ( 退出 )
ctrl + c
2.查询某个时间段的日志?
首先, 日志中要有程序记录的时间,然后在logs目录下执行此命令: ( 把这段时间的日志输出到新的文件中。 )
sed -n '/2021-12-01 11:30:/,/2021-12-01 11:40:/p' catalina.out > new.out
解析: ( 命令详解 )
sed -n '/年份-月份-日期 小时:分钟:/,/年份-月份-日期 小时:分钟:/p' catalina.out > 新的的文件名称.out
注意:
若catalina.out文件比较大, 可以就会比较慢, 等待一会就可以了!
3.扩展一个<清空>日志文件的命令? ( 你可能会用到 )
echo ' ' > catalina.out
why?
若日志文件过大, 可能会导致服务器磁盘空间满了, 有些接口可能不能正常访问. ( 此时就需要解决! )
通过这种方法,磁盘空间可以立即释放,进程可以继续向文件写入日志,但不必重启服务器。
1.实时查看当前项目的运行日志,进入logs目录,
tail -f catalina.out
扩展: ( 退出 )
ctrl + c
2.查询某个时间段的日志?
首先, 日志中要有程序记录的时间,然后在logs目录下执行此命令: ( 把这段时间的日志输出到新的文件中。 )
sed -n '/2021-12-01 11:30:/,/2021-12-01 11:40:/p' catalina.out > new.out
解析: ( 命令详解 )
sed -n '/年份-月份-日期 小时:分钟:/,/年份-月份-日期 小时:分钟:/p' catalina.out > 新的的文件名称.out
注意:
若catalina.out文件比较大, 可以就会比较慢, 等待一会就可以了!
3.扩展一个<清空>日志文件的命令? ( 你可能会用到 )
echo ' ' > catalina.out
why?
若日志文件过大, 可能会导致服务器磁盘空间满了, 有些接口可能不能正常访问. ( 此时就需要解决! )
通过这种方法,磁盘空间可以立即释放,进程可以继续向文件写入日志,但不必重启服务器。
12月1
对于weboffice这个active插件的使用上提供点说明。
首先在官网上下载weboffice7
下载weboffice7-exe.rar,weboffice7-x86.rar。解压后有个weboffice.exe和weboffice.cab
1、要使用这个插件,首先你得先在电脑安装weboffice.exe
由于这是activex插件,只支持ie,所以chrome,firefox是不支持的。所以有个ffactivex-setup-r39.rar可以提供兼容,这个需要先安装,再安装weboffice.exe 。weboffice.exe和ffactivex-setup-r39这两个安装包在你自己的web系统上可以写个js判断是否已经安装,是否ie,没有的话提供下载。
2、安装后,在你页面上的某个固定的div内嵌入个<object> 对象,这个<object>就是offcie对象。。可以看官网上的weboffice7-demo.rar。里面有个LoadWebOffice.js。我把内容拷出来,如下面。
var s = ""
s += "<object id=WebOffice1 height=768 width='100%' style='LEFT: 0px; TOP: 0px' classid='clsid:E77E049B-23FC-4DB8-B756-60529A35FAD5' codebase='WebOffice.cab#Version=7,0,1,0'>"
s +="<param name='_ExtentX' value='6350'><param name='_ExtentY' value='6350'>"
s +="</OBJECT>"
document.write(s)
就是返回一个object对象,其中之前下载weboffice.cab需要把地址写在codebase内。这个object对象的id是weboffice1,var obj=document.getElementById("WebOffice1") ;用obj就可以调用对这个offcie的各种操作了。具体api可以看官网提供的最后一个weboffice7-SDK.rar 。 如下面例子中就是在td内引入<object>。
<TD class=TableData vAlign=top width="85%">
<!-- -----------------------------== 装载weboffice控件 ==--------------------------------- -->
<SCRIPT src="LoadWebOffice.js"></SCRIPT>
<!-- --------------------------------== 结束装载控件 ==----------------------------------- -->
</TD>
3、假如需要兼容chrome和firefox。。在不同的浏览器下,这个<object>对象有不同的写法,具体可以参考论坛代码链接。
这个插件可以实现web在线offcie编辑,保存,修订,套红,印章等功能。勉强能用吧。。兼容的插件ffactivex-setup-r39其实是firefox的activex兼容,用在chrome需要在npi上启用,而且兼容效果比在firefox下差。
首先在官网上下载weboffice7
下载weboffice7-exe.rar,weboffice7-x86.rar。解压后有个weboffice.exe和weboffice.cab
1、要使用这个插件,首先你得先在电脑安装weboffice.exe
由于这是activex插件,只支持ie,所以chrome,firefox是不支持的。所以有个ffactivex-setup-r39.rar可以提供兼容,这个需要先安装,再安装weboffice.exe 。weboffice.exe和ffactivex-setup-r39这两个安装包在你自己的web系统上可以写个js判断是否已经安装,是否ie,没有的话提供下载。
2、安装后,在你页面上的某个固定的div内嵌入个<object> 对象,这个<object>就是offcie对象。。可以看官网上的weboffice7-demo.rar。里面有个LoadWebOffice.js。我把内容拷出来,如下面。
var s = ""
s += "<object id=WebOffice1 height=768 width='100%' style='LEFT: 0px; TOP: 0px' classid='clsid:E77E049B-23FC-4DB8-B756-60529A35FAD5' codebase='WebOffice.cab#Version=7,0,1,0'>"
s +="<param name='_ExtentX' value='6350'><param name='_ExtentY' value='6350'>"
s +="</OBJECT>"
document.write(s)
就是返回一个object对象,其中之前下载weboffice.cab需要把地址写在codebase内。这个object对象的id是weboffice1,var obj=document.getElementById("WebOffice1") ;用obj就可以调用对这个offcie的各种操作了。具体api可以看官网提供的最后一个weboffice7-SDK.rar 。 如下面例子中就是在td内引入<object>。
<TD class=TableData vAlign=top width="85%">
<!-- -----------------------------== 装载weboffice控件 ==--------------------------------- -->
<SCRIPT src="LoadWebOffice.js"></SCRIPT>
<!-- --------------------------------== 结束装载控件 ==----------------------------------- -->
</TD>
3、假如需要兼容chrome和firefox。。在不同的浏览器下,这个<object>对象有不同的写法,具体可以参考论坛代码链接。
这个插件可以实现web在线offcie编辑,保存,修订,套红,印章等功能。勉强能用吧。。兼容的插件ffactivex-setup-r39其实是firefox的activex兼容,用在chrome需要在npi上启用,而且兼容效果比在firefox下差。
11月18
在Windwos中,系统时间的设置很简单,界面操作,通俗易懂,而且设置后,重启,关机都没关系。系统时间会自动保存在BIOS时钟里面,启动计算机的时候,系统会自动在BIOS里面取硬件时间,以保证时间的不间断。但在Linux下,默认情况下,系统时间和硬件时间并不会自动同步。在Linux运行过程中,系统时间和硬件时间以异步的方式运行,互不干扰。硬件时间的运行,是靠BIOS电池来维持,而系统时间,是用CPU Tick来维持的。在系统开机的时候,会自动从BIOS中取得硬件时间,设置为系统时间。
1. Linux系统时间的设置
在Linux中设置系统时间,可以用date命令:
//查看时间
[root@node1 ~]# date
Tue Feb 25 20:15:18 CST 2014
//修改时间
[root@node1 ~]# date -s "20140225 20:16:00" #yyyymmdd hh:mm:ss
Tue Feb 25 20:16:00 CST 2014
//date 有多种时间格式可接受,查看date --help
2. Linux硬件时间的设置
硬件时间的设置,可以用hwclock或者clock命令。两者基本相同,只用一个就行,只不过clock命令除了支持x86硬件体系外,还支持Alpha硬件体系。
//查看硬件时间可以是用hwclock ,hwclock --show 或者 hwclock -r
[root@node1 ~]# hwclock --show
Tue 25 Feb 2014 08:21:14 PM CST -0.327068 seconds
//设置硬件时间
[root@node1 ~]# hwclock --set --date "20140225 20:23:00"
[root@node1 ~]# hwclock
Tue 25 Feb 2014 08:23:04 PM CST -0.750440 seconds
3. 系统时间和硬件时间的同步
同步系统时间和硬件时间,可以使用hwclock命令。
//以系统时间为基准,修改硬件时间
[root@node1 ~]# hwclock --systohc <== sys(系统时间)to(写到)hc(Hard Clock)
//或者
[root@node1 ~]# hwclock -w
//以硬件时间为基准,修改系统时间
[root@node1 ~]# hwclock --hctosys
//或者
[root@node1 ~]# hwclock -s
4. 不同机器之间的时间同步
为了避免主机时间因为长期运行下所导致的时间偏差,进行时间同步(synchronize)的工作是非常必要的。Linux系统下,一般使用ntp服务器来同步不同机器的时间。一台机器,可以同时是ntp服务端和ntp客户端。在生产系统中,推荐使用像DNS服务器一样分层的时间服务器来同步时间。
不同机器间同步时间,可以使用ntpdate命令,也可以使用ntpd服务。
1. Linux系统时间的设置
在Linux中设置系统时间,可以用date命令:
//查看时间
[root@node1 ~]# date
Tue Feb 25 20:15:18 CST 2014
//修改时间
[root@node1 ~]# date -s "20140225 20:16:00" #yyyymmdd hh:mm:ss
Tue Feb 25 20:16:00 CST 2014
//date 有多种时间格式可接受,查看date --help
2. Linux硬件时间的设置
硬件时间的设置,可以用hwclock或者clock命令。两者基本相同,只用一个就行,只不过clock命令除了支持x86硬件体系外,还支持Alpha硬件体系。
//查看硬件时间可以是用hwclock ,hwclock --show 或者 hwclock -r
[root@node1 ~]# hwclock --show
Tue 25 Feb 2014 08:21:14 PM CST -0.327068 seconds
//设置硬件时间
[root@node1 ~]# hwclock --set --date "20140225 20:23:00"
[root@node1 ~]# hwclock
Tue 25 Feb 2014 08:23:04 PM CST -0.750440 seconds
3. 系统时间和硬件时间的同步
同步系统时间和硬件时间,可以使用hwclock命令。
//以系统时间为基准,修改硬件时间
[root@node1 ~]# hwclock --systohc <== sys(系统时间)to(写到)hc(Hard Clock)
//或者
[root@node1 ~]# hwclock -w
//以硬件时间为基准,修改系统时间
[root@node1 ~]# hwclock --hctosys
//或者
[root@node1 ~]# hwclock -s
4. 不同机器之间的时间同步
为了避免主机时间因为长期运行下所导致的时间偏差,进行时间同步(synchronize)的工作是非常必要的。Linux系统下,一般使用ntp服务器来同步不同机器的时间。一台机器,可以同时是ntp服务端和ntp客户端。在生产系统中,推荐使用像DNS服务器一样分层的时间服务器来同步时间。
不同机器间同步时间,可以使用ntpdate命令,也可以使用ntpd服务。
11月18
架构
组件基本交流流程
核心对象
k8s常见操作
创建配置
$ vim examplepod.yml
在文件中填入如下内容并保存。
apiVersion: v1
kind: Pod
metadata:
name: examplepod
spec:
containers:
- name: examplepod-container
image: busybox
imagePullPolicy: IfNotPresent
command: ['sh', '-c']
args: ['echo "Hello Kubernetes!"; sleep 3600']
执行一个service
$ kubectl apply -f examplepod.yml
获取执行中的pod
$ kubectl get pod
获取单个pod
$ kubectl get pod {Pod名称}
持续监控
$ kubectl get pod {Pod名称} -w
详细参数
$ kubectl get pod {Pod名称} -o wide
输出详细参数
$ kubectl get pod examplepod --output yaml
$ kubectl get pod examplepod --output json
查看详细信息
$ kubectl describe pods {Pod名称}
查看日志
$ kubectl logs {Pod名称}
修改pod
$ kubectl replace -f {pod模板路径}
强制修改
kubectl replace -f example.yaml --force
删除pod
$ kubectl delete pod {Pod名称}
模板删除
$ kubectl delete -f {模板文件名称}
组件基本交流流程
核心对象
k8s常见操作
创建配置
$ vim examplepod.yml
在文件中填入如下内容并保存。
apiVersion: v1
kind: Pod
metadata:
name: examplepod
spec:
containers:
- name: examplepod-container
image: busybox
imagePullPolicy: IfNotPresent
command: ['sh', '-c']
args: ['echo "Hello Kubernetes!"; sleep 3600']
执行一个service
$ kubectl apply -f examplepod.yml
获取执行中的pod
$ kubectl get pod
获取单个pod
$ kubectl get pod {Pod名称}
持续监控
$ kubectl get pod {Pod名称} -w
详细参数
$ kubectl get pod {Pod名称} -o wide
输出详细参数
$ kubectl get pod examplepod --output yaml
$ kubectl get pod examplepod --output json
查看详细信息
$ kubectl describe pods {Pod名称}
查看日志
$ kubectl logs {Pod名称}
修改pod
$ kubectl replace -f {pod模板路径}
强制修改
kubectl replace -f example.yaml --force
删除pod
$ kubectl delete pod {Pod名称}
模板删除
$ kubectl delete -f {模板文件名称}
11月18
gitlab安装
docker启动gitlab 并配置端口号 因为要映射到外网 因此docker的第一个端口号要与外网端口号一致 防止新建的库端口号与访问地址不一致
docker run -d \
-p 80:30039 \
-p 443:443 \
-p 1022:22 \
--name gitlab \
--restart unless-stopped \
-v gitlab-config:/etc/gitlab \
-v gitlab-logs:/var/log/gitlab \
-v gitlab-data:/var/opt/gitlab \
twang2218/gitlab-ce-zh
修改配置文件/etc/gitlab/
配置 external_url 为新建库地址 smtp配置为邮件服务
external_url 'http://www.heckjj.com'
gitlab_rails['smtp_enable'] = true
gitlab_rails['smtp_address'] = "smtp.qq.com"
gitlab_rails['smtp_port'] = 25
gitlab_rails['smtp_user_name'] = "i@heckjj.com"
gitlab_rails['smtp_password'] = "OFJGZWLKJQVXWLHK"
gitlab_rails['smtp_domain'] = "qq.com"
gitlab_rails['smtp_authentication'] = "login"
gitlab_rails['smtp_enable_starttls_auto'] = true
gitlab_rails['smtp_tls'] = false
gitlab_rails['gitlab_email_from'] = "i@heckjj.com" #配置gitlab的配置的发信人
访问 http://www.heckjj.com/ 设置密码
登录账号:root
密码:设置的密码
git常见操作
命令行操作:
Git 全局设置
git config --global user.name "heck"
git config --global user.email "i@heckjj.com"
创建新版本库
git clone http://www.heckjj.com/heck/heck.git
cd heck
touch README.md
git add README.md
git commit -m "add README"
git push -u origin master
已存在的文件夹
cd existing_folder
git init
git remote add origin http://www.heckjj.com/heck/heck.git
git add .
git commit -m "Initial commit"
git push -u origin master
已存在的 Git 版本库
cd existing_repo
git remote rename origin old-origin
git remote add origin http://www.heckjj.com/heck/heck.git
git push -u origin --all
git push -u origin --tags
docker启动gitlab 并配置端口号 因为要映射到外网 因此docker的第一个端口号要与外网端口号一致 防止新建的库端口号与访问地址不一致
docker run -d \
-p 80:30039 \
-p 443:443 \
-p 1022:22 \
--name gitlab \
--restart unless-stopped \
-v gitlab-config:/etc/gitlab \
-v gitlab-logs:/var/log/gitlab \
-v gitlab-data:/var/opt/gitlab \
twang2218/gitlab-ce-zh
修改配置文件/etc/gitlab/
配置 external_url 为新建库地址 smtp配置为邮件服务
external_url 'http://www.heckjj.com'
gitlab_rails['smtp_enable'] = true
gitlab_rails['smtp_address'] = "smtp.qq.com"
gitlab_rails['smtp_port'] = 25
gitlab_rails['smtp_user_name'] = "i@heckjj.com"
gitlab_rails['smtp_password'] = "OFJGZWLKJQVXWLHK"
gitlab_rails['smtp_domain'] = "qq.com"
gitlab_rails['smtp_authentication'] = "login"
gitlab_rails['smtp_enable_starttls_auto'] = true
gitlab_rails['smtp_tls'] = false
gitlab_rails['gitlab_email_from'] = "i@heckjj.com" #配置gitlab的配置的发信人
访问 http://www.heckjj.com/ 设置密码
登录账号:root
密码:设置的密码
git常见操作
命令行操作:
Git 全局设置
git config --global user.name "heck"
git config --global user.email "i@heckjj.com"
创建新版本库
git clone http://www.heckjj.com/heck/heck.git
cd heck
touch README.md
git add README.md
git commit -m "add README"
git push -u origin master
已存在的文件夹
cd existing_folder
git init
git remote add origin http://www.heckjj.com/heck/heck.git
git add .
git commit -m "Initial commit"
git push -u origin master
已存在的 Git 版本库
cd existing_repo
git remote rename origin old-origin
git remote add origin http://www.heckjj.com/heck/heck.git
git push -u origin --all
git push -u origin --tags
11月18
最近在做了个数据大屏项目,客户需要在电脑开机时就打开大屏数据网站,于是就有了下面的想法。
首先使用记事本输入以下代码:
Set objShell = CreateObject("Wscript.Shell")
objShell.Run "microsoft-edge:http://www.heckjj.com"
wscript.sleep 5000
objShell.SendKeys "{F11}"
然后另存为fullscreen.vbs文件
快捷键win+r 输入
shell:startup
命令
将脚本或脚本快捷方式放入该文件夹中,该文件用于存放开机启动的程序,或者直接在注册表里添加。
首先使用记事本输入以下代码:
Set objShell = CreateObject("Wscript.Shell")
objShell.Run "microsoft-edge:http://www.heckjj.com"
wscript.sleep 5000
objShell.SendKeys "{F11}"
然后另存为fullscreen.vbs文件
快捷键win+r 输入
shell:startup
命令
将脚本或脚本快捷方式放入该文件夹中,该文件用于存放开机启动的程序,或者直接在注册表里添加。
11月18
问题描述
最近,公司的开发服务器总是偶尔有一些java服务莫名其妙的停掉。通过排查发现是内存不足,奇怪的是,内存只是用了一半,但是可用的却只有不到1G(峰值时估计更少)。下面是具体的内存使用信息:
可以看到,可用的内存只有888M,内存共有62G,罪魁祸首就是这个buff/cache占用了27G。
产生原因
Linux操作系统频繁存取文件会导致内存被用光,即便是程序结束后也不会被正常释放,这就会导致buffers和cached占用过高。
首先,简单了解一下buff/cache的介绍:
total:是指计算机总物理内存;
used:已用的内存;
free:空余的内存;
total = used + free总内存;
shared:被多个进程共享的内存;
buffers:用于存放要输出到disk(块存储)的数据,在这里buff是指被OS buffer住的内存;
cached:存放从disk上读出的数据;buffer和cache是为了提高IO性能并由OS管理。
解决方法
Linux具有先进的缓存机制,会针对dentry、Buffer Cache(针对磁盘块的读写)和Page Cache(针对文件inode的读写)进行缓存操作用来提高读写效率。但是在进行了大量文件操作之后,缓存会把内存资源基本用光,虽然文件读取效率提高了,但是物理内存会逐渐被吃光。
因为服务进行了频繁的文件读写操作,但是为什么操作系统不会主动回收呢,原来是因为drop_caches的默认参数设置的就是不释放的。
drop_caches的值可以是0-3之间的数字,代表不同的含义:
0:不释放(系统默认值)
1:释放页缓存
2:释放dentries和inodes
3:释放所有缓存
我们可以用下面的命令来释放缓存:
# sync
# echo 1 > /proc/sys/vm/drop_caches
# echo 2 > /proc/sys/vm/drop_caches
# echo 3 > /proc/sys/vm/drop_caches
# sync
执行完命令后,free -h 查看内存,发现可用内存已经达到27G,buff/cache也被释放。
这样只是暂时解决问题,我们可以写一个脚本配合定时任务来定时检查清除缓存:
#!/bin/bash
Mem=$(free -m | awk 'NR==2' | awk '{print $4}')
if [ $Mem -gt 1024 ];
then
echo "Service memory capacity is normal!" > /dev/null
else
sync
echo "1" > /proc/sys/vm/drop_caches
echo "2" > /proc/sys/vm/drop_caches
echo "3" > /proc/sys/vm/drop_caches
sync
fi
最后,只需将脚本加入定时任务,即可!
最近,公司的开发服务器总是偶尔有一些java服务莫名其妙的停掉。通过排查发现是内存不足,奇怪的是,内存只是用了一半,但是可用的却只有不到1G(峰值时估计更少)。下面是具体的内存使用信息:
可以看到,可用的内存只有888M,内存共有62G,罪魁祸首就是这个buff/cache占用了27G。
产生原因
Linux操作系统频繁存取文件会导致内存被用光,即便是程序结束后也不会被正常释放,这就会导致buffers和cached占用过高。
首先,简单了解一下buff/cache的介绍:
total:是指计算机总物理内存;
used:已用的内存;
free:空余的内存;
total = used + free总内存;
shared:被多个进程共享的内存;
buffers:用于存放要输出到disk(块存储)的数据,在这里buff是指被OS buffer住的内存;
cached:存放从disk上读出的数据;buffer和cache是为了提高IO性能并由OS管理。
解决方法
Linux具有先进的缓存机制,会针对dentry、Buffer Cache(针对磁盘块的读写)和Page Cache(针对文件inode的读写)进行缓存操作用来提高读写效率。但是在进行了大量文件操作之后,缓存会把内存资源基本用光,虽然文件读取效率提高了,但是物理内存会逐渐被吃光。
因为服务进行了频繁的文件读写操作,但是为什么操作系统不会主动回收呢,原来是因为drop_caches的默认参数设置的就是不释放的。
drop_caches的值可以是0-3之间的数字,代表不同的含义:
0:不释放(系统默认值)
1:释放页缓存
2:释放dentries和inodes
3:释放所有缓存
我们可以用下面的命令来释放缓存:
# sync
# echo 1 > /proc/sys/vm/drop_caches
# echo 2 > /proc/sys/vm/drop_caches
# echo 3 > /proc/sys/vm/drop_caches
# sync
执行完命令后,free -h 查看内存,发现可用内存已经达到27G,buff/cache也被释放。
这样只是暂时解决问题,我们可以写一个脚本配合定时任务来定时检查清除缓存:
#!/bin/bash
Mem=$(free -m | awk 'NR==2' | awk '{print $4}')
if [ $Mem -gt 1024 ];
then
echo "Service memory capacity is normal!" > /dev/null
else
sync
echo "1" > /proc/sys/vm/drop_caches
echo "2" > /proc/sys/vm/drop_caches
echo "3" > /proc/sys/vm/drop_caches
sync
fi
最后,只需将脚本加入定时任务,即可!