一般识别爬虫的方法是通过 UserAgent,这种办法最直接,但也很容易伪造,先不管这个了。

实现在 Nginx 中使用 map 指令来匹配一个变量:

map $http_user_agent $is_bot {
    default 0;
    ~[a-z]bot[^a-z] 1;
    ~[sS]pider[^a-z] 1;
    'Yahoo! Slurp China' 1;
    'Mediapartners-Google' 1;
}

在这里我们生成了一个名为 $is_bot 的变量,该变量默认值是 0 ,如果匹配到上述 4 种正则表达式的情况后,值就变成1。你可以继续往 map 中添加新的表达式规则。
然后在 location 中使用该变量:

location / {
    error_page 418 =200 @bots;
    if ($is_bot) {
       return 418;
    }
    proxy_pass http://tomcat_for_normal_visitors;
}

@bots 的定义:

location @bots {
    proxy_pass http://tomcat_for_bot;
}

当判断当前请求是爬虫的时候,返回 418 错误码。
通过 error_page 将 418 错误码改为 200 (正常请求响应码),然后进入 @bots 这个 location 进行下一步处理。@bots 中将请求反向代理到你指定的后端应用。

如此便可将正常的用户访问和爬虫访问独立开来,使二者不会互相影响。

首页你必需拿到主机(就是在主机上操作,不是远程连接上可以操作的)
很多时候我们都会忘记Linux root 用户的口令,下面就教大家如果忘记root口令怎么办

第1步:开机后在启动菜单上定位到系统所启动的选项上,按“e”进入编辑。
第2步:在linux16这行按END键在后面输入“ rd.break console=tty0”,然后按“ctrl+x“,进入到了系统的紧急求援模式
第3步:依次输入以下命令:

#mount –o remount,rw /sysroot
#chroot /sysroot
#passwd

输入新的root密码,2次确认,然后继续

#touch /.autorelabel
#exit
#exitroot

输完以后,系统会重启,输入我们刚才配置的密码登录就行
至此,密码破解完毕

那么怎么来预防别人通过这种方式来破密呢,就是给系统加上第二首锁:
使用 grub2-mkpasswd-pbkdf2 命令生成hash密码
编辑文件/etc/grub.d/文件夹下任意文件,通常编辑10_linux

在末尾添加如下几行:

cat <<EOF
set superusers="admin"
password_pbkdf2 admin xxxxxxxxxx
EOF

xxxxxx就是hash密码,或者用文明密码就是换成
password admin 123456这样

更新grub配置后并重启

#grub2-mkconfig -o /boot/grub2/grub.cfg
#reboot

当你重启过后想输入e编辑启动脚本时,要求认证输入上方的用户名admin和密码123456,才能进入,没错我们再上一把锁,不过有时候也许会坑自己,除非你的确需要这样做

不过这样做了,也有第三招来破密,这里就不写了

文档
https://www.bootcss.com/p/bootstrap-datetimepicker/index.htm

基础方法

依赖
需要bootstrap的下拉菜单组件 (dropdowns.less) 的某些样式,还有bootstrap的sprites (sprites.less and associated images) 中的箭头图标。

A standalone .css file (including necessary dropdown styles and alternative, text-based arrows) can be generated by running build/build_standalone.less through the lessc compiler:

$ lessc build/build_standalone.less datetimepicker.css
选项
所有需要"Date" 的选项都可以处理Date 对象; a String formatted according to the given format; or a timedelta relative to today, eg '-1d', '+6m +1y', etc, where valid units are 'd' (day), 'w' (week), 'm' (month), and 'y' (year).

你也可以指定一个符合 ISO-8601 格式的日期时间,就可以忽略下面的格式:

yyyy-mm-dd
yyyy-mm-dd hh:ii
yyyy-mm-ddThh:ii
yyyy-mm-dd hh:ii:ss
yyyy-mm-ddThh:ii:ssZ

format
String. 默认值: 'mm/dd/yyyy'

日期格式, p, P, h, hh, i, ii, s, ss, d, dd, m, mm, M, MM, yy, yyyy 的任意组合。

p : meridian in lower case ('am' or 'pm') - according to locale file
P : meridian in upper case ('AM' or 'PM') - according to locale file
s : seconds without leading zeros
ss : seconds, 2 digits with leading zeros
i : minutes without leading zeros
ii : minutes, 2 digits with leading zeros
h : hour without leading zeros - 24-hour format
hh : hour, 2 digits with leading zeros - 24-hour format
H : hour without leading zeros - 12-hour format
HH : hour, 2 digits with leading zeros - 12-hour format
d : day of the month without leading zeros
dd : day of the month, 2 digits with leading zeros
m : numeric representation of month without leading zeros
mm : numeric representation of the month, 2 digits with leading zeros
M : short textual representation of a month, three letters
MM : full textual representation of a month, such as January or March
yy : two digit representation of a year
yyyy : full numeric representation of a year, 4 digits

weekStart
Integer. 默认值:0

一周从哪一天开始。0(星期日)到6(星期六)

startDate
Date. 默认值:开始时间

The earliest date that may be selected; all earlier dates will be disabled.

endDate
Date. 默认值:结束时间

The latest date that may be selected; all later dates will be disabled.

daysOfWeekDisabled
String, Array. 默认值: '', []

Days of the week that should be disabled. Values are 0 (Sunday) to 6 (Saturday). Multiple values should be comma-separated. Example: disable weekends: '0,6' or [0,6].

autoclose
Boolean. 默认值:false

当选择一个日期之后是否立即关闭此日期时间选择器。

startView
Number, String. 默认值:2, 'month'

日期时间选择器打开之后首先显示的视图。 可接受的值:

0 or 'hour' for the hour view
1 or 'day' for the day view
2 or 'month' for month view (the default)
3 or 'year' for the 12-month overview
4 or 'decade' for the 10-year overview. Useful for date-of-birth datetimepickers.
minView
Number, String. 默认值:0, 'hour'

日期时间选择器所能够提供的最精确的时间选择视图。

maxView
Number, String. 默认值:4, 'decade'

日期时间选择器最高能展示的选择范围视图。

todayBtn
Boolean, "linked". 默认值: false

如果此值为true 或 "linked",则在日期时间选择器组件的底部显示一个 "Today" 按钮用以选择当前日期。如果是true的话,"Today" 按钮仅仅将视图转到当天的日期,如果是"linked",当天日期将会被选中。

todayHighlight
Boolean. 默认值: false

如果为true, 高亮当前日期。

keyboardNavigation
Boolean. 默认值: true

是否允许通过方向键改变日期。

language
String. 默认值: 'en'

The two-letter code of the language to use for month and day names. These will also be used as the input's value (and subsequently sent to the server in the case of form submissions). Currently ships with English ('en'), German ('de'), Brazilian ('br'), and Spanish ('es') translations, but others can be added (see I18N below). If an unknown language code is given, English will be used.

forceParse
Boolean. 默认值: true

当选择器关闭的时候,是否强制解析输入框中的值。也就是说,当用户在输入框中输入了不正确的日期,选择器将会尽量解析输入的值,并将解析后的正确值按照给定的格式format设置到输入框中。

minuteStep
Number. 默认值: 5

此数值被当做步进值用于构建小时视图。对于每个 minuteStep 都会生成一组预设时间(分钟)用于选择。

pickerReferer : 不建议使用
String. 默认值: 'default' (other value available : 'input')

The referer element to place the picker for the component implementation. If you want to place the picker just under the input field, just specify input.

pickerPosition
String. 默认值: 'bottom-right' (还支持 : 'bottom-left')

此选项当前只在组件实现中提供支持。通过设置选项可以讲选择器放倒输入框下方。

viewSelect
Number or String. 默认值: same as minView (supported values are: 'decade', 'year', 'month', 'day', 'hour')

With this option you can select the view from which the date will be selected. By default it's the last one, however you can choose the first one, so at each click the date will be updated.

showMeridian
Boolean. 默认值: false

This option will enable meridian views for day and hour views.

initialDate
Date or String. 默认值: new Date()

You can initialize the viewer with a date. By default it's now, so you can specify yesterday or today at midnight ...

标记
组件模版。

<div class="input-append date" id="datetimepicker" data-date="12-02-2012" data-date-format="dd-mm-yyyy">
    <input class="span2" size="16" type="text" value="12-02-2012">
    <span class="add-on"><i class="icon-th"></i></span>
</div>  

带有重置按钮(用于清空输入框)的组件模版。

<div class="input-append date" id="datetimepicker" data-date="12-02-2012" data-date-format="dd-mm-yyyy">
    <input class="span2" size="16" type="text" value="12-02-2012">
    <span class="add-on"><i class="icon-remove"></i></span>
    <span class="add-on"><i class="icon-th"></i></span>
</div>      

方法
.datetimepicker(options)
初始化日期时间选择器。

remove
参数: None

移除日期时间选择器。同时移除已经绑定的event、内部绑定的对象和HTML元素。

$('#datetimepicker').datetimepicker('remove');

show
参数: None

显示日期时间选择器。

$('#datetimepicker').datetimepicker('show');

hide
参数: None

隐藏日期时间选择器。

$('#datetimepicker').datetimepicker('hide');

update
参数: None

使用当前输入框中的值更新日期时间选择器。

$('#datetimepicker').datetimepicker('update');

setStartDate
参数:

startDate (String)
给日期时间选择器设置一个新的起始日期。

$('#datetimepicker').datetimepicker('setStartDate', '2012-01-01');

Omit startDate (or provide an otherwise falsey value) to unset the limit.

$('#datetimepicker').datetimepicker('setStartDate');
$('#datetimepicker').datetimepicker('setStartDate', null);

setEndDate
参数:

endDate (String)
给日期时间选择器设置结束日期。

$('#datetimepicker').datetimepicker('setEndDate', '2012-01-01');

Omit endDate (or provide an otherwise falsey value) to unset the limit.

$('#datetimepicker').datetimepicker('setEndDate');
$('#datetimepicker').datetimepicker('setEndDate', null);

setDaysOfWeekDisabled
参数:

daysOfWeekDisabled (String|Array)
Sets the days of week that should be disabled.

$('#datetimepicker').datetimepicker('setDaysOfWeekDisabled', [0,6]);

Omit daysOfWeekDisabled (or provide an otherwise falsey value) to unset the disabled days.

$('#datetimepicker').datetimepicker('setDaysOfWeekDisabled');
$('#datetimepicker').datetimepicker('setDaysOfWeekDisabled', null);

事件(Events)
Datetimepicker 类暴露了一组event用以对日期进行操作。

show
当选择器显示时被触发。

hide
当选择器隐藏时被触发。

changeDate
当日期被改变时被触发。

$('#date-end')
.datetimepicker()
.on('changeDate', function(ev){
    if (ev.date.valueOf() < date-start-display.valueOf()){
        ....
    }
});

changeYear
当十年视图上的年视图view被改变时触发。

changeMonth
当年视图上的月视图view被改变时触发。

outOfRange
当用户选择的日期超出startDate 或endDate 时,或者通过setDate 或 setUTCDate方法设置日期超出范围时被触发。

键盘支持
日期时间选择器提供了键盘导航:

up, down, left, right 方向键
这些方向键中,left/right 向后/向前 一天,up/down 向后/向前 一周。

配合shift键,up/left 向后退一个月,down/right 向前进一个月。

配置ctrl键,up/left 向后退一年,down/right 向前进一年。

Shift+ctrl 和 ctrl 同等效果 - 也就是说,他们不能同时改变月和年,只能单独改变年。

escape
escape 键可以用来隐藏、重新显示日期时间选择器;当用户希望手工编辑输入框中的值是会很有用。

enter
当选择器处于显示状态时,enter键只是将其隐藏。当选择器处于隐藏状态时,enter键发挥通常的功能 - 提交当前表单,或者其他。

I18N国际化
本插件支持月、每周中天的名称、weekStart选项的国际化。默认是语言是English ('en');其它可以使用的翻译文件在js/locales/ 目录中,只需在本插件之后引入需要的语言文件即可。需要增加额外语言支持的话,只需向 $.fn.datetimepicker.dates中增加一个key即可,一定要放在调用 .datetimepicker()之前。如下案例:

$.fn.datetimepicker.dates['en'] = {
    days: ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"],
    daysShort: ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"],
    daysMin: ["Su", "Mo", "Tu", "We", "Th", "Fr", "Sa", "Su"],
    months: ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"],
    monthsShort: ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"],
    today: "Today"
};

Right-to-left languages may also include rtl: true to make the calendar display appropriately.

If your browser (or those of your users) is displaying characters wrong, chances are the browser is loading the javascript file with a non-unicode encoding. Simply add charset="UTF-8" to your script tag:

<script type="text/javascript" src="bootstrap-datetimepicker.de.js" charset="UTF-8"></script>

使用
绑定输入框,并设置format选项:

<input type="text" value="2012-05-15 21:05" id="datetimepicker">
$('#datetimepicker').datetimepicker({
    format: 'yyyy-mm-dd hh:ii'
});

绑定输入框,并设置format标记:

<input type="text" value="2012-05-15 21:05" id="datetimepicker" data-date-format="yyyy-mm-dd hh:ii">
$('#datetimepicker').datetimepicker();

作为组件使用:

<div class="input-append date" id="datetimepicker" data-date="12-02-2012" data-date-format="dd-mm-yyyy">
    <input size="16" type="text" value="12-02-2012" readonly>
    <span class="add-on"><i class="icon-th"></i></span>
</div>
$('#datetimepicker').datetimepicker();

作为内联日期时间选择器:

<div id="datetimepicker"></div>
$('#datetimepicker').datetimepicker();

获取日期对象

$("#startTime").data("datetimepicker").getDate()

获取时间截毫秒

$("#startTime").data("datetimepicker").getDate().getTime()

扩展文件名: CDbBICommand.php ,将文件放于 \protected\components 目录下,确定项目会自动引入这个目录的文件,然后用法:
StatVisitor 是 CActiveRecord 类的数据表模型

$bi = new CDbBICommand(new StatVisitor());
$bi->batchInsert([['name'=>123],['name'=>234]]);

扩展文件代码如下:

<?php

/**
 * class for sql batch insert
 * eg:
 * $bi = new CDbBICommand(new StatVisitor());
 * $bi->batchInsert([['name'=>123],['name'=>234]]);
 */
class CDbBICommand {

    /**
     * CDbBICommand constructor.
     * @param CActiveRecord $acModel
     */
    public function __construct($acModel) {
        $this->ac = $acModel;
        $this->tablename = $this->ac->tableName();
        $this->db = $this->ac->getDbConnection();
        $this->command = $this->db->createCommand();
    }

    public function batchInsert($array_columns) {
        $sql    = '';
        $params = array();
        $i      = 0;
        foreach ($array_columns as $columns) {
            $names        = array();
            $placeholders = array();
            foreach ($columns as $name => $value) {
                if (!$i) {
                    $names[] = $this->db->quoteColumnName($name);
                }
                if ($value instanceof CDbExpression) {
                    $placeholders[] = $value->expression;
                    foreach ($value->params as $n => $v) {
                        $params[$n] = $v;
                    }
                } else {
                    $placeholders[]           = ':' . $name . $i;
                    $params[':' . $name . $i] = $value;
                }
            }
            if (!$i) {
                $sql = 'INSERT INTO ' . $this->db->quoteTableName($this->tablename)
                       . ' (' . implode(', ', $names) . ') VALUES ('
                       . implode(', ', $placeholders) . ')';
            } else {
                $sql .= ',(' . implode(', ', $placeholders) . ')';
            }
            $i++;
        }
        return $this->command->setText($sql)->execute($params);
    }
}

框架自带的批量插入方法,很少有网络资料:

$builder = Yii::app()->db->schema->commandBuilder; // 创建builder对象
$command = $builder->createMultipleInsertCommand('{{umeng_message}}', array( // umeng_message为数据库表
    array(// 格式为:'字段' => '值', 不包括主键ID,一个array为一条记录
        'msg_id' => $android['data']['task_id'],
        'detail' => $android['data']['json'],
        'msg_detail_id_fk' => $detailId
    ),
    array(
        'msg_id' => $android['data']['task_id'],
        'detail' => $android['data']['json'],
        'msg_detail_id_fk' => $detailId
    ),
));
$command->execute(); // 执行成功返回true

转的别人的文章:https://blog.csdn.net/weixin_40735752/article/details/88077362
在一主一从或一主多从的mysql架构中,当主库不可用时,需要及时切换到从库,那么,如何判断主库是否可用?

通过select 1来判断
方案
在sql中执行"select 1",如果失败,则认为sql服务不可用。

优点
简单,速度快

缺点
只能检测sql服务器进程是否存在,并不能真正识别服务的可用性。
比如,当innodb_thread_concurrency设置过小时(比如=1),大部分查询可能因为需要排队等待而无法实时响应时,select 1反而可以实时响应。

通过实际的查表语句来检测
方案
在系统库mysql库中创建一个 health_check表,并且里面只放一行数据,然后定期执行"select * from mysql.health_check"

优点
简单,可以检测出因为并发线程过多而导致的数据库不可用的情况。

缺点
由于只采用读来检测,所以类似磁盘满而导致的服务不可用问题,是无法检测出来的。

通过更新表来检测
方案
简单地改进上一种方法,通过更新表来实现可用性检测。
update mysql.health_check set t_modified = now();
上述语句执行时,会写binlog文件,如果磁盘满时,执行会失败,因此,可以检测出磁盘不可用等io问题。

缺点
在主从的mysql结构里面,如果主备关系是双M结构,这时如果在备库也执行这个命令,就会出现主备冲突,导致主备同步停止。

改进
在health_check表中创建两列,一列是id,一列是t_modified_time,每个服务器只update id=自己的serverid的行,这样就可以 保证主备库各自的检测命令不冲突。

改进后的缺点
改进后的更新表方案已经相对比较完善了,但是还是有些问题,主要的问题是可能出现“判定慢”。当服务器由于资源紧张时,大部分复杂的查询更新语句可能实质上已经超时,但是由于检测语句相对比较简单,可能不会超时(或者有时候超时,有时候会成功),因此出现判定慢或者判定不准确的问题。

通过sql内部的性能数据来检测可用性
方案
通过统计mysql的每一次io请求的时间,来判定服务是否可用。
mysql 5.6版本以后提供了performance_schema库,在file_summary_by_event_name表里面统计了每次io请求的时间。
performance_schema是可选项,全部打开性能统计会影响mysql的性能,大概下降10%左右。因此只需要enable少数需要的项进行统计。
比如打开 redo log的时间监控,可以执行:
update setup_instruments set ENABLED=‘YES’, Timed = ‘YES’ where name like ‘%wait/io/file/innodb/innodb_log_file%’;
假设已经打开了redo log和binlog这两个统计信息,接下来就是检测是否存在每次IO请求超过200ms的事件:
select event_name, MAX_TIMER_WAIT from performance_schema.file_summary_by_event_name where event_name in (‘wait/io/file/innodb/innodb_log_file’, ‘wait/io/file/sql/binlog’) and MAX_TIMER_WAIT > 200 * 100010001000;
发现异常以后,可以读取需要的信息,然后通过以下语句清空之前的统计信息,以便监控后续可能出现的异常:
truncate table performance_shema.file_summary_by_event_name;

优点
比较可靠

缺点
太复杂
————————————————
版权声明:本文为CSDN博主「greensea669」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/weixin_40735752/java/article/details/88077362