Monthly Archives: 10月 2017

10月 30th, 2017

修改 sshd_config 端口

$ vi /etc/ssh/sshd_config

取消 #Port 22 的注释,在下一行添加你需要修改的新端口 Port 2048。(这里不删除 22 端口是为了防止修改后新端口无法访问,造成无法用 ssh 连接服务器。)

Port 22

Port 2048

修改保存 sshd_config 文件后重启 sshd 服务:

$  systemctl restart sshd

退出 ssh 会话后,再用新的端口连接:

$ ssh -p 2048 root@example.com

ssh: connect to host 0.0.0.0 port 2048: Connection refused

好吧,native 了……对于 CentOS 7 这一套修改端口的方法已经不能生效了。

 

打开 SELinux 端口

SELinux 全称 Security Enhanced Linux (安全强化 Linux),是 MAC (Mandatory Access Control,强制访问控制系统)的一个实现,目的在于明确的指明某个进程可以访问哪些资源(文件、网络端口等)。

对于 ssh,SELinux 默认只允许 22 端口,我们可以用 SELinux 管理配置工具 semanage,来修改 ssh 可访问的端口。

安装 semanage 工具

$ yum provides semanage

$ yum -y install policycoreutils-python

为 ssh 打开 2048 端口

# 为 ssh 添加新的允许端口$ semanage port -a -t ssh_port_t -p tcp 2048# 查看当前 SELinux 允许的端口$ semanage port -l | grep sshssh_port_t                     tcp      2048, 22

错误处理

当 SELINUX 配置为禁用状态时,使用 semanage 会报错提示无法读取 policy 文件:

SELinux:  Could not downgrade policy file /etc/selinux/targeted/policy/policy.30, searching for an older version.

SELinux:  Could not open policy file <= /etc/selinux/targeted/policy/policy.30:  No such file or directory

/sbin/load_policy:  Can’t load policy:  No such file or directory

libsemanage.semanage_reload_policy: load_policy returned error code 2. (No such file or directory).

FileNotFoundError: [Errno 2] No such file or directory

修改 /etc/selinux/config 配置,启用 SELinux:

 

$ vi /etc/selinux/config

SELINUX=permissive

# 重启服务器$ init 6# 重启后查看 SELinux 状态$ sestatus# if it shows disable, you can run$ load_policy -qi

检查配置:

$ semanage port -a -t ssh_port_t -p tcp 2048

$ semanage port -l | grep sshssh_port_t                     tcp      2048, 22

# 重启 ssh 服务systemctl restart sshd

注:semange 不能禁用 ssh 的 22 端口:

$ semanage port -d -t ssh_port_t -p tcp 22

ValueError: 在策略中定义了端口 tcp/22,无法删除。

配置防火墙 firewalld

启用防火墙 && 查看防火墙状态:

$ systemctl enable firewalld

$ systemctl start firewalld

$ systemctl status firewalld

  • service – firewalld – dynamic firewall daemon

Loaded: loaded (/usr/lib/systemd/system/firewalld.service; enabled; vendor preset: enabled)

Active: active (running) since 二 2016-12-20 02:12:59 CST; 1 day 13h ago

Main PID: 10379 (firewalld)

CGroup: /system.slice/firewalld.service

└─10379 /usr/bin/python -Es /usr/sbin/firewalld –nofork –nopid

$ firewall-cmd –state

running

查看防火墙当前「默认」和「激活」zone(区域):

$ firewall-cmd –get-default-zone

public

$ firewall-cmd –get-active-zones

public

interfaces: eth0 eth1

若没有激活区域的话,要执行下面的命令。

激活 public 区域,增加网卡接口:

Bash

$ firewall-cmd –set-default-zone=public

$ firewall-cmd –zone=public –add-interface=eth0

success

$ firewall-cmd –zone=public –add-interface=eth1

success

为 public zone 永久开放 2048/TCP 端口:

# 以防新端口不生效,先把 22 端口暴露$ firewall-cmd –permanent –zone=public –add-port=22/tcp

$ firewall-cmd –permanent –zone=public –add-port=2048/tcp

success

# 重载防火墙$ firewall-cmd –reload# 查看暴露端口规则$ firewall-cmd –permanent –list-port

443/tcp 80/tcp 22/tcp 2048/tcp

$ firewall-cmd –zone=public –list-all

public (default, active)

interfaces: eth0 eth1

sources:

services: dhcpv6-client ssh

ports: 443/tcp 80/tcp 22/tcp 2048/tcp

masquerade: no

forward-ports:

icmp-blocks:

rich rules:

退出 ssh 后,尝试连接新端口

$ ssh -p 2048 root@example.com

成功登录的话,就可以做收尾工作了。

禁用 22 端口

删除 ssh 允许端口

$ vi /etc/ssh/sshd_config#Port 22Port 2048

$ systemctl restart sshd# 用 ss 命令检查 ssh 监听的端口,没有 22 证明修改成功$ ss -tnlp | grep sshLISTEN     0      128                       *:2048                    *:*      users:((“sshd”,18233,3))

防火墙移除 22 端口

$ firewall-cmd –permanent –zone=public –remove-port=22/tcp

success

$ firewall-cmd –reload

$ firewall-cmd –permanent –list-port

443/tcp 80/tcp 2048/tcp

ssh 取消监听 22 端口,就已经配置好了,防火墙只不过是在 ssh 外多一层访问限制。如果要做的更好还可以将 22 端口的访问流量转向访问者本地:

$ firewall-cmd –permanen –zone=public –add-forward-port=port=22:proto=tcp:toport=22:toaddr=127.0.0.1# 配置后重载防火墙,用 ssh -p 22 root@example.com 就会访问到自己本地的 22 端口。

若要删除 forward 配置,可以:

$ firewall-cmd –permanen –zone=public –remove-forward-port=port=22:proto=tcp:toport=22:toaddr=127.0.0.1

检验修改 ssh 端口是否成功:

$ ssh -p 22 root@example.com# 无响应,因为转到了本地的 22 端口# 若防火墙未 forward 连接,则会回显 “ssh: connect to host {ip} port 22: Connection refused”$ ssh -p 2048 root@example.com# 成功 success

 

 

10月 30th, 2017

你可以用两个方法做到这个:

方法 1

编辑文件/etc/sysctl.conf,

vi /etc/sysctl.conf

添加下面的行:

net.ipv6.conf.all.disable_ipv6 =1
net.ipv6.conf.default.disable_ipv6 =1

如果你想要为特定的网卡禁止IPv6,比如,对于enp0s3,添加下面的行。

net.ipv6.conf.enp0s3.disable_ipv6 =1

保存并退出文件。

执行下面的命令来使设置生效。

sysctl -p

方法 2

要在运行的系统中禁止IPv6,依次输入下面的命令:

echo 1>/proc/sys/net/ipv6/conf/all/disable_ipv6
echo 1>/proc/sys/net/ipv6/conf/default/disable_ipv6

或者

sysctl -w net.ipv6.conf.all.disable_ipv6=1
sysctl -w net.ipv6.conf.default.disable_ipv6=1

就是这样。现在IPv6已经禁止了。

我在禁止IPv6后遇到问题怎么办

你可能在禁止IPv6后遇到一些问题

问题1:

如果你在禁止IPv6后SSH遇到问题,按照下面的做。

编辑 /etc/ssh/sshd_config 文件

vi /etc/ssh/sshd_config

找到下面的行:

#AddressFamily any

把它改成:

AddressFamily inet

或者,在这行的前面去掉注释(#):

#ListenAddress 0.0.0.0

接着重启ssh来使改变生效。

systemctl restart sshd

问题2:

如果你在禁止Ipv6后启动postfix遇到问题,编辑/etc/postfix/main.cf:

vi /etc/postfix/main.cf

注释掉配置中的localhost部分,并且使用ipv4回环。

#inet_interfaces = localhost
10月 30th, 2017

删除:

  1. yum remove mysql mysql-server mysql-devel mysql-libs compat-mysql51 mysql-community-client mysql-community-libs mysql-community-server mysql-community-common mysql-community-release.noarch
  2. rm -rf /var/lib/mysql
  3. rm /etc/my.cnf
  4. rm -rf /var/lib/mysql/
  5. rm -rf /usr/lib64/mysql
  6. rm -rf /usr/lib/mysql
  7. rm -rf /usr/share/mysql
  8. rm –rf /usr/my.cnf
  9. rm -rf /root/.mysql_sercret
  10. chkconfig –del mysqld

验证:

  1. yum list installed mysql*
10月 30th, 2017

也许会碰到这样的问题:

有一张表有几十个或者上百个字段,备份后删除了一部分数据,过后发现问题需要恢复其中一部分数据,但有几个字段不需要恢复(比如100个字段,只需恢复97个)

初学阶段:

对于一个初学者可能是个噩梦:”oh, my god! 难道要手打97个字段???”,一边从网上找案例,一边苦思冥想,折腾十几分钟,最终还是手打…

入门阶段:

对于了解数据库但不是很擅长编写sql语句(涉及系统表)的技术人员:”嗯…这个可以从建表语句或者用sp_help table_name拿到所有字段,只需要将字段复制出来整理一下…”,于是复制粘贴,改字段加符号,处理了几分钟

进阶阶段:

对于熟悉数据及编写sql语句的技术人员:”系统表里面存放表的字段信息,在查询字段时可以把不需要的字段剔除,拼接出可直接用于执行的语句…”,几分钟后,敲出代码:

declare @into_table_name varchar(50)

declare @select_table_name varchar(50)

declare @except_columns varchar(100)

declare @where_condition varchar(500)

–原表

set @into_table_name=”

–备份表

set @select_table_name=”

–排除的字段

set @except_columns=”

–where条件

set @where_condition=’ where 1=2′

declare @insert_str varchar(max)

declare @column_str varchar(max)

–拼接字段

set @column_str=(

select b.name+’,’

from sysobjects a,syscolumns b

where a.id=b.id

and a.name=@table_name

and b.name not in(@except_columns)

for xml path(”))

–删除末尾逗号

select @column_str=substring(@column_str,1,len(@column_str)-1)

–拼接sql语句

set @insert_str=’insert into ‘+@into_table_name+'(‘+@column_str+’) select ‘+@column_str+’ from ‘+@select_table_name+@where_condition

select @insert_str

检查无误后:exec(@insert_str)

类似的问题再次出现

初学者:”##$#@!@#!@#%$#%…”

入门者:”唉…”

进阶者笑了笑,从容不迫的替换参数,十几秒后一切搞定…

10月 30th, 2017

故障描述

本案例是HP P2000的存储vmware exsi虚拟化平台,由RAID-5由10块lT硬盘组成,其中6号盘是热备盘,由于故障导致RAID-5磁盘阵列的两块盘掉线,表现为两块硬盘亮黄灯。 经用户方维护人员检测,故障硬盘应为物理故障,表现为:序列号无法读取,在SAS扩展卡上硬盘无法识别。

数据备份与修复

故障发生后用户方工程师与我公司联系,经过详细咨询,了解到故障比较严重,必须把RAID-5磁盘阵列带到我公司进行检测,检测RAID-5的每块成员盘是物理故障(磁头损坏或者盘片划伤)还是逻辑故障。由于情况紧急,工程师在接到原盘以后,立即着手准备检测。对能识别的好盘用连接到北亚镜像服务器上使用WinHex做扇区级镜像,同时对不能识别的坏盘进行检测。

首先将坏盘连接到外部的SAS扩展卡上,加电后通过硬盘工作声音判断硬盘电机能够起转,但是磁头没有进行寻道操作,于是尝试把硬盘PCB分离下来对HDA组件氧化部分进行清洁操作,将PCB还原后故障依旧。于是和客户沟通使用6号热备盘的好PCB替换到故障盘上进行尝试性修复,再将故障盘PCB上的ROM芯片替换到6号盘的好PCB上面后硬盘工作时起转和磁头寻道声音都正常,但是在寻道结束后,有明显的敲盘声音,于是判断有可能磁头损坏。在和用户沟通后尝试使用6号热备盘中的好磁头对故障盘进行替换操作以读取数据。在无尘室对故障盘进行开盘更换磁头操作后,将故障盘连接到专业硬盘维修工作上进行检测,发现故障盘已经不能识别,数据无法读取。

因为用户有两块故障盘,之前尝试修复的都是其中一块,再次和客户沟通尝试对另一块故障盘进行修复操作。和先前的故障盘一样,这块盘的故障依旧是磁头损坏,因为用户的HP OEM盘价格昂贵,于是尝试在网上购买ST原厂的相同型号硬盘进行磁头更换。这块硬盘的磁头更换完成后,设备能够正常识别硬盘,于是将故障盘所有扇区完整镜像到一块相同容量的备份盘中。

 

重组RAID-5步骤

【判断起始扇区】所有硬盘都镜像好后就可以重组了,用WinHex打开9块盘(热备盘不需要加进去重组),先把镜像文件解析成磁盘。可以看到这9块盘的0扇区都有“55 AA”标志,如图1所示。

5bcf85b2ce07d098eaba1e53cb8a8f4c.png-wh_

图1

查找结果如图2所示,0x01C2H处表示该分区的类型,这里显示“05”,代表这是一个扩展分区。因此从0扇区看这是一个不正常的MBR分区结构。

26440521d21e59687c98fb4ac079092e.png-wh_

图2

按图1方式继续往下找,分别在9号盘和8号盘找到了“55 AA”的标志。9号盘查询结果如图3所示。这是一个正常的MBR分区,其0x01C6处数值代表指向的下一个扇区为GPT的头部。

98ae484d84a2ac3e13b536bbd3f581d7.png-wh_

图3

8号盘查询结果如图4所示。其0x01C6处数值代表指向下一个扇区。但是下一个扇区很明显不是GPT的头部。

12ac5b27a27b6e643698b5a8842eb830.png-wh_

图4

由此可以确定9号盘是第一块盘,8号盘可能是最后一块盘。GPT分区所在扇区起始于172032扇区,因此初步确定LUN的起始扇区是172032扇区。

【判断条带(stripe)大小】条带也称块,它是RAID处理数据的基本单元。不同的RAID其条带大小有所不同。RAID-5的1个条带组中有1个校验区,1个校验区的大小等于1个条带的大小,根据这一点,针对这个RAID-5案例做分析。如果对VMFS的文件系统不熟悉,可以通过比较法确定条带大小。如某一条带组中的校验区跟这一条带组中的非校验区可能相差的很明显,通过WinHex查看并做对比,就可以找到条带大小。本案例判断出一个条带是1024个扇区。

【判断RAID-5成员盘盘序】按照1024扇区分割,使一个记录为一个条带的大小,如图5所示。并且9块盘跳到同一记录283123。

212d42591033eae01d858aa7c52ee3c8.png-wh_

图5

当9块盘都定位到同一位置时,通过对比可以判断校验区的走向,继而判断整个RAID-5的走向。之前已经判断出9号盘是第一块盘了,把9号盘放在第一个位置,接着就可以判断走向了,结果如图6所示(drive9是第4块盘)。确定RAID-5为左走向,盘序为9,2,3,4,10,1,7,8,5。

2e29cf1827eacb143b8f7b60935ff907.png-wh_

图6

前面内容初步确定了LUN的起始扇区是172032扇区。用WinHex跳到172032扇区,观察各硬盘实际情况。如果172032扇区是LUN的起始扇区,那么这个扇区所属条带中的5号盘应该是校验区,但是此条带中却显示8号盘是检验区,根据本案例RAID-5的左走向,5号盘的校验区应该在172032-1024=171008扇区,即上一个条带。跳转到171008扇区,发现校验区为5号盘。因此可以确定LUN的起始扇区为171008扇区。

【重组RAID-5】使用专业恢复工具按照确定的盘序组好,添加进去,如图7所示。选择RAID-5,Stripe size 512KB,左异步。

0e9ef2e9d2e2c25021f24870e136e65b.png-wh_

图7

 

点击Build进行重组。组好后,由于数据从1024*8=8192个扇区开始,若专业恢复工具没有跳转到此扇区的功能,那么刚组好的RAID必须和一个文件再进行一次Build重组操作。RAID的起始扇区(Start sectors)选择8192,这个文件可以任意选择起始扇区和大小大小(Count sectors),如图8和图9所示,图10是组好的RAID-5。

3d09f29c9f2b5d6792a758b2ecd5462c.png-wh_

图8

95f56bfca855eeee0f54facae154f5fe.png-wh_

图9

571a937c231fd3fdf5051f9694b5bf60.png-wh_

图10

移交数据

整个RAID-5就重建好后,由我公司商务联系用户方验收数据,用户方确定数据没问题,签订完验收合同后,完整的RAID-5数据即可移交。移交时根据用户方要求把数据移交到用户方带来的新盘上。恢复完的数据保留在我公司服务器上3天,之后数据自动被系统销毁。

10月 30th, 2017

1  概述


本文将介绍ngx_http_upstream_module模块和ngx_stream_core_module模块这两个模块实现nginx的调度功能。nginx可以通过proxy功能,实现将不同内容的访问调度到对应的机器上。实现了应用级的调度,相关内容见博客《Nginx  之  实现代理功能》


2  ngx_http_upstream_module模块


该模块用于将多个服务器定义成服务器组,而由proxy_pass,fastcgi_pass等指令进行引用.注意,如果nginx上有设置了proxy_cache.那么访问的资源如果在nginx上已经有缓存了,将不会把请求转发给后台的服务器,直接把将缓存返回给客户端,就不会有调度的执行,可能同一访问的得到的结果是相同的。

.1、upstream 

upstream  name { … }

定义后端服务器组,会引入一个新的上下文,默认调度算法是wrr

Context: http

1
2
3
4
5
upstream httpdsrvs{
server ...
server...
...
}

.2、server

server  address [parameters];

在upstream上下文中server成员,以及相关的参数;Context:upstream

address的表示格式:

unix:/PATH/TO/SOME_SOCK_FILE

IP[:PORT]

HOSTNAME[:PORT]

parameters:

weight=number 权重,默认为1

max_conns连接后端报务器最大并发活动连接数,1.11.5后支持

max_fails=number失败尝试最大次数;超出此处指定的次数时,server将被标记为不可用,默认为1

fail_timeout=time后端服务器标记为不可用状态的连接超时时长,默认10s

backup将服务器标记为“备用”,即所有服务器均不可用时才启用,相当于是sorry server,提示用户,注意,这里backup不要用80端口,用其他的虚拟主机来充当sorry server,如再开一个端口8000

down标记为“不可用”,配合ip_hash使用,实现灰度发布,灰度发布,指分批进行发布上线。

.3、ip_hash

源地址hash调度方法

根据源地址进行调度,同一个源的客户端调度到同一台主机

.4、least_conn

最少连接调度算法,当server拥有不同的权重时其为wlc,当所有后端主机连接数相同时,则使用wrr,适用于长连接

.5、hash 

hash   key [consistent]基于指定的key的hash表来实现对请求的调度,此处的key可以直接文本、变量或二者组合

作用:将请求分类,同一类请求将发往同一个upstream server,使用consistent参数,将使用ketama一致性hash算法,适用于后端是Cache服务器(如varnish)时使用

hash $request_uri  consistent; #其中,consistent一致性的hash

hash $remote_addr;

.6、keepalive 连接数N;

keepalive n;

为每个worker进程保留的空闲的长连接数量,可节约nginx端口,并减少连接管理的消耗

.7、health_check 

health_check [parameters];

健康状态检测机制;只能用于location上下文

常用参数:

interval=time检测的频率,默认为5秒

fails=number:判定服务器不可用的失败检测次数;默认为1次

passes=number:判定服务器可用的失败检测次数;默认为1次

uri=uri:做健康状态检测测试的目标uri;默认为/

match=NAME:健康状态检测的结果评估调用此处指定的match配置块

注意:仅对nginxplus有效,nginxplus为商业版,需要付费

.8  match

match name { … }

对backendserver做健康状态检测时,定义其结果判断机制;只能用于http上下文

.常用的参数:

status  code[ code …]: 期望的响应状态码

headerHEADER[operator value]:期望存在响应首部,也可对期望的响应首部的值基于比较操作符和值进行比较

body:期望响应报文的主体部分应该有的内容

注意:仅对nginx plus有效

例子

http配置段如下

1
2
3
4
5
6
7
8
9
10
11
12
13
vim  /etc/nginx/nginx.conf
http {
......
    upstream websrvs {
        server 172.18.50.61:80 weight=1;
        #server 172.18.50.61:80 weight=1 down;
        server 172.18.50.65:80 weight=2;
        server 127.0.0.1:8000 backup;
        #ip_hash;
        #least_conn;
        #hash $request_uri;
            
}

server配置段如下

1
2
3
    location / { 
        proxy_pass http://websrvs;
   }

3  ngx_stream_core_module模块

实现代理基于TCP,UDP (1.9.13),UNIX-domain sockets的数据流。工作于传输层的反向代理或调度器,这个是和http配置段平行的配置。

.1  proxy_pass

proxy_pass  address;指定后端服务器地址

.2  proxy_timeout

proxy_timeout  timeout;无数据传输时,保持连接状态的超时时长,默认为10m

.3 proxy_connect_timeout

proxy_connect_timeout  time;设置nginx与被代理的服务器尝试建立连接的超时时长,默认为60s

4  语法格式

.4.1、stream{ … }

定义stream相关的服务;Context:main

1
2
3
4
5
6
7
8
9
10
11
stream {
upstream telnetsrvs{
server 192.168.22.2:23; 
server 192.168.22.3:23; 
least_conn;
}
server {
listen 10.1.0.6:23;
proxy_pass  telnetsrvs;
}
}

.4.2、listen

1
listen address:port [ssl] [udp][proxy_protocol]  [backlog=number] [bind][ipv6only=on|off] [reuseport] [so_keepalive=on|off [keepidle]:[keepintvl]:[keepcnt]];

5  示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
vim  /etc/nginx/nginx.conf
stream {
upstream telnetsrvs {
    server 172.18.50.61:23;
    server 172.18.50.75:23;
    least_conn;
        }
server {
    listen  2323; #注意,这里的端口不能是代理服务器上已经使用的端口,如23,否则将不会调度
proxy_pass telnetsrvs;
proxy_timeout 60s;
proxy_connect_timeout10s;
        }
}

TAGS:
10月 30th, 2017
首先你要了解一下Python之禅,一行代码输出“The Zen of Python”:

python -c “import this”
“””
The Zen of Python, by Tim Peters
Beautiful is better than ugly.
Explicit is better than implicit.
Simple is better than complex.
Complex is better than complicated.
Flat is better than nested.
Sparse is better than dense.
Readability counts.
Special cases aren’t special enough to break the rules.
Although practicality beats purity.
Errors should never pass silently.
Unless explicitly silenced.
In the face of ambiguity, refuse the temptation to guess.
There should be one– and preferably only one –obvious way to do it.
Although that way may not be obvious at first unless you’re Dutch.
Now is better than never.
Although never is often better than *right* now.
If the implementation is hard to explain, it’s a bad idea.
If the implementation is easy to explain, it may be a good idea.
Namespaces are one honking great idea — let’s do more of those!
“””

从“The Zen of Python”也能看出,Python倡导Beautiful、Explicit、Simple等原则,当然我们接下来要介绍的一行Python能实现哪些好玩的功能,可能和Explicit原则相违背。

如果你有其他这方面的小例子,也欢迎评论,我会加到文章中,文章也许会长期更新。
(1)一行代码启动一个Web服务

python -m SimpleHTTPServer 8080 # python2
python3 -m http.server 8080 # python3

(2)一行代码实现变量值互换

a, b = 1, 2; a, b = b, a
(3)一行代码解决FizzBuzz问题:
FizzBuzz问题:打印数字1到100, 3的倍数打印“Fizz”, 5的倍数打印“Buzz”, 既是3又是5的倍数的打印“FizzBuzz”

for x in range(1, 101): print(“fizz”[x % 3 * 4:]+”buzz”[x % 5 * 4:] or x)

(4)一行代码输出特定字符”Love”拼成的心形

print(‘\n’.join([”.join([(‘Love'[(x-y) % len(‘Love’)] if ((x*0.05)**2+(y*0.1)**2-1)**3-(x*0.05)**2*(y*0.1)**3 <= 0 else ‘ ‘) for x in range(-30, 30)]) for y in range(30, -30, -1)]))

(5)一行代码输出Mandelbrot图像
Mandelbrot图像:图像中的每个位置都对应于公式N=x+y*i中的一个复数

print(‘\n’.join([”.join([‘*’if abs((lambda a: lambda z, c, n: a(a, z, c, n))(lambda s, z, c, n: z if n == 0 else s(s, z*z+c, c, n-1))(0, 0.02*x+0.05j*y, 40)) < 2 else ‘ ‘ for x in range(-80, 20)]) for y in range(-20, 20)]))

(6)一行代码打印九九乘法表

print(‘\n’.join([‘ ‘.join([‘%s*%s=%-2s’ % (y, x, x*y) for y in range(1, x+1)]) for x in range(1, 10)]))

(7)一行代码计算出1-100之间的素数(两个版本)

print(‘ ‘.join([str(item) for item in filter(lambda x: not [x % i for i in range(2, x) if x % i == 0], range(2, 101))]))
print(‘ ‘.join([str(item) for item in filter(lambda x: all(map(lambda p: x % p != 0, range(2, x))), range(2, 101))]))

(8)一行代码输出斐波那契数列

print([x[0] for x in [(a[0], a.append([a[1], a[0]+a[1]])) for a in ([[1, 1]], ) for i in range(30)]])

(9)一行代码实现快排算法

    • qsort = lambda arr: len(arr) > 1 and qsort(list(filter(lambda x: x <= arr[0], arr[1:]))) + arr[0:1] + qsort(list(filter(lambda x: x > arr[0], arr[1:]))) or arr

(10)一行代码解决八皇后问题

  • [__import__(‘sys’).stdout.write(‘\n’.join(‘.’ * i + ‘Q’ + ‘.’ * (8-i-1) for i in vec) + “\n========\n”) for vec in __import__(‘itertools’).permutations(range(8)) if 8 == len(set(vec+i for i in range(8))) == len(set(vec-i for i in range(8)))]


(11)一行代码实现数组的flatten功能: 将多维数组转化为一维

  • flatten = lambda x: [y for l in x for y in flatten(l)] if isinstance(x, list) else [x]


(12)一行代码实现list, 有点类似与上个功能的反功能

  • array = lambda x: [x[i:i+3] for i in range(0, len(x), 3)]


(13)一行代码实现求解2的1000次方的各位数之和

  • print(sum(map(int, str(2**1000))))

 

TAGS:
10月 30th, 2017

1、什么是上传和下载?

–  数据上传是指客户端向服务器上传数据,客户端向服务器发送的所有请求都属于数据上传。文件上传是数据上传的一种特例,指的是客户端向服务器上传文件。即将保存在客户端的文件上传至服务器中的一个副本,保存到服务器中。

–   数据下载是指客户端从服务器上获取数据的过程。文件下载是数据下载的一种特例,指的是客户端从服务器下载文件,即将原来保存在服务器中的文件下载到客户端中一个副本保存。通常我们对服务器所发出的请求,大多数是文件下载请求,从服务器中下载文本、图片、声音、视频等文件,然后由客户端浏览器对这些文件进行解析后,才可能看到这些多媒体信息。

–  但是我们这里所说的文件下载,指的是文件从服务器下载到浏览器后,浏览器并不直接解析,而是以附件的形式保存到客户端中。

–  上传与下载的文件可以是文本文件、图片、声音、视频等各种类型。

b8f92803d83bf1eeb80b10fbce113a91.png

2、文件上传的实现:

a、上传时对表单的要求:

–  文件上传要求客户端表单提交特殊的请求–multipart请求,即包含多部分数据的请求。所以文件上传表单对于表单数据的编码类型要求,必须为multipart/form-data。即要为<form>标签指定enctype属性值为“multipart/form-data”。(enctype,即encodingtype,编码类型。)

–  由于客户端上传文件的大小是不确定的,所以HTTP协议规定,文件上传的数据要存放于请求正文中,而不能够出现在url的地址栏中,因为地址栏中可以存放的数据量太小。也就是说,文件上传的表单,必须提交POST请求,而不能够提交GET请求。

23a26a65cfe7c6b1dc5580e44b9df7dc.png

b、使用第三方工具实现文件上传:

–  需要使用到两个jar包:commons-fileupload-1.3.3.jar和commons-io-2.6.jar,jar包可以在apache官网中下载(commons-fileupload-1.3.3.jar依赖于commons-io-2.6.jar,如果只使用fileupload jar包,会运行程序时会抛出异常)

–  示例代码如下:

–  在index.jsp文件中填写的代码如下所示:

2fa75419bc90658bfde414ccaace60b4.png

– 为web应用添加一个Servlet,在web.xml文件中添加配置信息:

f48d3786832f863a3a9040d67d06d6c3.png

–  自定义serlvet类,在doPost方法中编写简单实现文件上传的代码:

bf00d1a00b4fb45347508f08e3538a8f.png

–  启动web应用,访问index.jsp,添加图片后,点击“上传”,可以发现控制台打印结果,在工作空间web项目的指定目录可以看到图片已经上传:(在Eclipse中,默认会把Web项目放到Eclipse的工作空间下的.metadata\.plugins\org.eclipse.wst.server.core\tmp0(或者是tmp1)\wtpwebapps\下)

b21e32099f0c94dbd9f2c5ce326a994f.png

729ee6601f720fb6fd4c181782ac64b3.png

314014bfe306dd1b3104d4a0c3cccff5.png

–  FileUploadServlet类中的代码相关解释:(也包含使用fileupload jar包文件上传时的常用方法)

–  org.apache.commons.fileupload.disk.DiskFileItemFactory类:默认的FileItemFactory实现类。这个实现创建FileItem实例(文件条目)。如果是小条目,会将其存入内存中,如果是大条目,会将其存入硬盘中的临时文件。大小条目数据的临界值,是可配置的。

91f1190a16a81a93e97408f2bd99b76b.png

–  setRepository(File repository)方法:设置临时存储文件(这个文件大小大于指定配置临界值)存放的目录位置。

–  setSizeThreshold(int sizeThreshold)方法:设置临界值(单位为字节),当超过这个值时文件将会直接写入硬盘中。(如sizeThreshold为1024 * 1024,则为1兆)

8a74cc4e8caa684bf269b300c189b40d.png

–  org.apache.commons.fileupload.servlet.ServletFileUpload类:处理文件上传的高级API。(如何存储各个部分的数据是由创建它们的工厂决定;给定的部分可能在内存中、磁盘上或者其他地方)

9c3076d9c62c9f9776b5195657472c23.png

–  parseRequest方法:解析请求,获取FileItem类型元素的List对象:

ff0d0aefa0fbc00c740f398a0a637473.png

–  ServletFileUpload类的父类org.apache.commons.fileupload.FileUploadBase的方法:

–  设置每个item的头部字符编码,其可以解决文件名的中文乱码问题:(若tomcat版本较低时,可能会出现文件名中文乱码)

b3a6b7eea773e4b8ebd511b28023c444.png

–  setFileSizeMax(long fileSizeMax)方法设置单个上传文件允许上传的最大边界值。

–  setSizeMax(long sizeMax)方法设置一次上传所有文件的总和最大边界值。(单位都为字节)

f901e54502e4278348b152c03449577e.png

8017fa8425940edd962e9e9a10e20d1a.png

–  isMultipartContent(HttpServletRequest request)方法:判断该请求是否包含multipart内容

8618a209ca6c1659043e646ea7cccc40.png

–  org.apache.commons.fileupload.FileItem接口:表示在multipart/form-data的POST请求中内的一个文件或者表单条目。

1f9e35cac9e80e53f4a390644a76cfec.png

–  isFormField方法:判断FileItem实例是否为一个普通form项:

5eefe2a855a7948e14135b4a880c8e03.png

–  getFieldName方法:获取对应文件条目(即单个表单项)的name属性值:

be8a739ea055325c48ae810618218c29.png

–  getName方法:获取客户端文件系统中的原上传文件名:(包含后缀名)

795af79e3b6ec7c2e381e0d6d9a9031a.png

–  getInputStream方法:获取输入流,用于取出上传文件中的内容:

8de79b5a5c3a09749d73d093dd334d49.png

–  delete方法:删除任何相关联的临时磁盘文件:

e12b9cb5850a53fbffb4cd2f2bf68a89.png

3、文件下载的实现:

a、超链接下载:将下载资源作为超链接的链接目标文件出现。若浏览器可以解析该资源文件,则将在浏览器上直接显示文件内容;若浏览器不支持该文件的解析,则会弹出另存为对话框,要求用户保存。

–  该下载方式的缺点很明显,不同的浏览器,以及相同的浏览器所安装的插件不同,那么其对于资源的解析能力也就不同,其是否弹出另存为对话框的情况也就不一样。决定权由浏览器掌握。

–  如在jsp文件中添加如下代码,在ff浏览器中点击,直接在浏览器中打开该图片:

e4d08a49cb50400b656faf31c560867c.png

b、Servlet方式的文件下载:

–  示例代码:

–  jsp文件中的内容和web.xml文件中添加的配置:

695609a242b68865df8a6ea3016f6786.png

d3d6402faa2673bb661ffa7358127a35.png

–  自定义Servlet类中添加如下代码:

46f022c912973e64c35f98421c07ec76.png

–  如果想要浏览器下载的方式是以附件的形式下载,需要修改响应的头部属性content-disposition值为attachment;filename=文件名 + 后缀名。(filename表示以附件形式下载显示的文件名)

javax.servlet.ServletContext接口的getResourceAsStream方法:获取web应用中的指定路径下的资源,以字节输入流InputStream的形式返回。

9974aebf2e1671c4a312cfe30c016d58.png

–  启动web应用,点击超链接后,可以看到文件以附件的形式下载:

e4f78ad2d6a233bc7e5460214d89d0b8.png

4、附加说明:

–  上传文件目录的管理:当用户上传的文件过多,而单个目录能够存放的文件个数有限,(windows系统下单文件夹中最大可有65,534个文件)所以需要上传的文件有时需要分目录进行管理。

–   可以使用java.io.File类的mkdir()方法来在当前目录中创建直接子目录,或者使用mkdirs()方法创建当前目录的多层子目录:

de46eac949cf2dbf440d624822609a0f.png

cc09c6e9d0f6817a27352d4e29589681.png

TAGS:
10月 30th, 2017

查询当前的标识列值:
SELECT IDENT_CURRENT(‘dbo.StayPushShipping’)
SELECT IDENT_INCR(‘dbo.StayPushShipping’)
SELECT IDENT_SEED (‘dbo.StayPushShipping’)

对于普通的表,用TRUNCATE TABLE
TRUNCATE TABLE name可以删除表内所有值并重置标识值 ,但是表内的数据将丢失。

对于配置了复制的表,先用DELETE删掉数据后,再DBCC CHECKIDENT
DBCC CHECKIDENT (‘dbo.StayPushShipping’, RESEED,1)

你想要重置标识值(不删除数据)采用下面方法即可:但是存在问题:
1)DBCC CHECKIDENT (‘表名’, RESEED,new_value)(重置新的标识值,new_value为新值)
2) 问题:如dbcc checkident (‘表名’,reseed,1)即可,但如果表内有数据,则重设的值如果小于当前表
的标识最大值,再插入数据时未指定插入的标识值,这样会导致标识冲突问题,如果你的标识设置成自
增的。此外,你也可以用 dbcc checkident(‘表名’,reseed),即可自动重设值,最后生成值。

10月 30th, 2017

在某地,用git clone 下载 github上的仓库的时候,速度很慢,才几十k每秒,稍微大点的仓库,要等到猴年马月。一直用git clone从github上下载源码学习,但是有时候git clone速度好慢,只有几Kb的速度,按这个速度下载有些源码的话估计要下一年。

然后我再网上找各种教程,试过通过vps下载github的源码,速度还是很慢,不知道是不是我用的vps刚好屏蔽了github。有人说git clone用的是另一个域名来下载的:global-ssl.fastly.Net,难怪我在hosts里面加了github.com的dns还是没解决问题。

github加速的方法如下:

1.用记事本打开hosts文件

Windows上的hosts文件路径在

C:\Windows\System32\drivers\etc\hosts

Linux的hosts文件路径在:

sudo vim /etc/hosts

2. 在hosts文件末尾添加两行

  • 151.101.72.249 http://global-ssl.fastly.net
  • 192.30.253.112 http://github.com

3.重启电脑,让hosts文件生效。

你会发现git clone的速度快很多。

TAGS: