varnish web cache服务
varnish介绍
缓存开源解决方案:
- varnish
- 充分利用epoll机制(能显著提高程序在大量并发连接中只有少量活跃的情况下的系统CPU利用率),并发量大,单连接资源较轻
- squid
- 在较大并发下,稳点性好,老当益壮
varnish:是一个轻量级的Cache和高性能的反向代理软件,通常为httpd提供缓存。
官方站点: http://www.varnish-cache.org/
varnish架构:
varnish拥有俩套配置文件;一套配置文件用于varnish自身进程的参数配置,另一套用于定义缓存规则;定义缓存规则需要使用灵活的语言来定义,这就是VCL(varnish语言);应用时需要将VCL编写的规则送给VCC编译后才能运行,所以安装varnish需要依赖gcc编译器。
- Manager Process
- 管理进程,相当于nginx的主控进程,不处理用户请求
- Cacher Process
- 线程Storage:完成缓存存储管理
- 线程Log/Stats:日志记录----->存入共享内存Shared Memory Log中
- 线程Worker threads:真正处理用户请求,通过线程池来定义,最大并发(线程池*线程池最大并发)
- shared memory log
- varnishlog:读取日志文件,保存在磁盘中
- varnishstat:读取统计数据,计数器
- VCL配置接口:varnish配置语言
- varnishadm:让varnish加载新配置文件
- VCC Process:varnish的c编译器
安装(centos 7中varnish被收入epel仓库)
yum -y install varnish
程序环境
配置文件:
- /etc/varnish/varnish.params(/etc/sysconfig/varnishd):配置varnish服务进程的工作特性(监听地址和端口,缓存机制等)
- /etc/varnish/default.vcl:配置各Child/Cache线程的工作特性
主程序:
- /usr/sbin/varnishd
CLI interface:
- /usr/bin/varnishadmin:通过此管理工具,完成与Manager Process的交互,进而控制varnish的工作特性
Share Memory Log交互工具:
- /usr/bin/varnishhist:日志历史
- /usr/binvarnishlog:记录详细log(请求报文首部,响应报文首部等)
- /usr/bin/varnishcsa:格式化记录日志
- /usr/bin/varnishstat:日志统计
- /usr/bin/varnishtop:日志排序分析
测试工具程序:
- /usr/bin/varnishtest
VCL配置文件重载程序:
- /usr/sbin/varnish_reload_vcl:此程序会编译配置文件
Systemd Unit File:
- /usr/lib/systemd/system/varnish.service:varnish服务
- /usr/lib/systemd/system/varnishlog.service:原始记录日志(保存磁在盘上)
- /usr/lib/systemd/system/varnishncsa.service:ncsa格式日志(保存磁在盘上)
arnish的缓存存储机制(Storage Types):
- malloc[,size]:内存存储,[,size]用于定义空间大小,重启后所有缓存项失效
- file[,path[,size[,granularity]]]:文件存储,黑盒,重启后所有缓存项失效
- persistent,path,size:文件存储,黑盒,重启后所有缓存项有效(试验阶段)
varnish的程序选项
- 程序选项:/etc/varnish/varnish.params文件;
- -a address[:port][,address[:port][...]:默认为6081端口;
- -T address[:port]:默认为6082端口;
- -s [name=]type[,options]:定义缓存存储机制;
- -u user
- -g group
- -f config:VCL配置文件;
- -F:运行于前台;
- 运行时参数:/etc/varnish/varnish.params文件, DEAMON_OPTS
- DAEMON_OPTS="-p thread_pool_min=5 -p thread_pool_max=500 -p thread_pool_timeout=300"
- -p param=value:设定运行参数及其值,可重复使用多次
- -r param[,param...]:设定指定的参数为只读状态
重载vcl配置文件:
# varnish_reload_vcl
varnishadm
# varnishadm -S /etc/varnish/secret -T 127.0.0.1: #登录管理程序
help [<command>] 获取帮助
ping [<timestamp>] 测试服务器
auth <response>
quit 退出cli
banner
status 显示状态
start 启动
stop 停止
vcl.load <configname> <filename> 加载VCL配置文件
vcl.inline <configname> <quoted_VCLstring>
vcl.use <configname> 激活VCL配置文件
vcl.discard <configname> 删除VCL配置
vcl.list 列出VCL配置
param.show [-l] [<param>] 列出当前运行的参数
param.set <param> <value> 运行参数临时调整
panic.show
panic.clear
storage.list 列出数据存储信息
vcl.show [-v] <configname> 列出VCL详细配置
backend.list [<backend_expression>] 列出后端服务器
backend.set_health <backend_expression> <state>
ban <field> <operator> <arg> [&& <field> <oper> <arg>]...
ban.list
配置文件
默认配置文件:
RELOAD_VCL=
VARNISH_VCL_CONF=/etc/varnish/default.vcl #指定加载VCL配置文件
VARNISH_LISTEN_ADDRESS=192.168.1.5 #服务监听的地址
VARNISH_LISTEN_PORT= #默认监听端口
VARNISH_ADMIN_LISTEN_ADDRESS=127.0.0.1 #管理服务监听的地址
VARNISH_ADMIN_LISTEN_PORT= #管理服务监听的端口
VARNISH_SECRET_FILE=/etc/varnish/secret #连接秘钥
VARNISH_STORAGE="malloc,256M" #用内存提供保存缓存,大小为256M
VARNISH_USER=varnish #用户身份
VARNISH_GROUP=varnish #组身份
DAEMON_OPTS="-p thread_pool_min=5 -p thread_pool_max=500 -p thread_pool_timeout=300" #指定进程的运行参数
缓存流程图解
- 一个请求进入,varnish收下这个请求,判断是否对这个请求做处理
- 访问控制,直接拒绝
- 请求方法不识别,直接找后端服务器响应
- 正常请求,进入下一步
- 查询此请求方法是否能缓存
- 不能缓存(如post,put),交给vcl_fetcg,由vcl_fetch投递给后端服务器响应
- 能缓存,进入下一步
- vcl_hash基于hash查找缓存中是否有对应资源
- 如果命中,从本地缓存中直接响应给客户端
- 若未命中,通过vcl_fetch到后端服务器取回资源,然后先缓存,再响应给客户端
VCL
Varnish配置语言(VCL)是一种特定于域的语言,用于描述Varnish Cache的请求处理和文档缓存策略。加载新配置时,由Manager进程创建的VCC进程将VCL代码转换为C.此C代码通常由gcc共享对象编译。然后将共享对象加载到cacher进程中。
VCL状态引擎切换
- vcl_recv收到请求,查找vcl_hash
- 若命中(传递值hit),交由vcl_hit
- hit命中,直接从缓存中响应,交由vcl_deliver投递给客户端
- vcl_hash -(hit)-> vcl_hit --> vcl_deliver
- 未命中(传递值miss),交由vcl_miss
- 交由vcl_backend_fetch请求后端服务器
- vcl_hash -(miss)-> vcl_miss --> vcl_backend_fetch --> vcl_backend_response --> vcl_deliver
- 若要删除缓存项(传递值purge),交由vcl_purge
- 交由vcl_synh管理缓存,删除对应缓存
- vcl_hash -(purge)-> vcl_purge --> vcl_synth
- 若不能理解请求(传递值pipe),交由vcl_pipe,请求被直接送至后端服务器
- vcl_hash -(pipe)-> vcl_pipe
- 并发连接超出(传递值busy),进入waiting状态,会等待重新请求查询缓存
- 传递值(pass,hit-for-pass),交由vcl_pass
- vcl_hit和vcl_miss也能交由给pass
- 两个特殊引擎:
- vcl_init:在处理任何请求之前要执行的vcl代码:主要用于初始化vMODS
- vcl_fini:所有的请求都已经结束,在vcl配置被丢弃时调用,主要用于清理vMODS
vainish默认的VCL配置
默认VCL配置也叫做隐式规则,在配置文件中无法看到,即使我们修改了配置文件,默认配置规则也是在最后做处理。
varnish> vcl.show -v boot #在客户端cli工具中查看
sub vcl_recv {
if (req.method == "PRI") { #如果客户端的请求方法是PRI,不支持SPDY或HTTP/2.0
return (synth()); #则构建一个405的包响应给客户端
}
if (req.method != "GET" && #如果客户端的请求方法不是GET
req.method != "HEAD" && #并且不是HEAD
req.method != "PUT" && #并且不是PUT
req.method != "POST" && #并且不是...
req.method != "TRACE" &&
req.method != "OPTIONS" &&
req.method != "DELETE") {
return (pipe); #即,不是标准HTTP请求方法的交给pipe(管道)
}
if (req.method != "GET" && req.method != "HEAD") { #请求方法不是GET和HEAD的
return (pass); #交给pass处理,也就是除了GAT和HEAD方法其他的无法缓存
}
if (req.http.Authorization || req.http.Cookie) { #http的请求首部包含Authorization(认证)或Cookie,即个人专有信息
return (pass); #交给pass处理,因为这些带有个人信息的数据无法缓存
}
return (hash); #以上的规则都没有做处理的请求交给hash做处理,剩下的是可以查询缓存的请求了
} sub vcl_pipe
sub vcl_pass
sub vcl_hash
sub vcl_purge
sub vcl_hit
sub vcl_miss
sub vcl_deliver
sub vcl_synth
sub vcl_backend_fetch
sub vcl_backend_response
sub vcl_backend_error
sub vcl_init
sub vcl_fini
VCL语法格式
- 文件开始要注明vcl版本号:vcl 4.0;
- //,#,/*,*/为注释
- 子例行Subroutines使用sub关键字;例如sub_recv {...};
- 不支持循环,但支持条件语法,支持內建变量(受限于引擎)
- 使用一个keyword基于return函数终止当前状态引擎,并决定交给哪一个状态引擎
- “域”专用配置,在一个状态引擎中的配置只对当前状态引擎有效
VCL Finite State MAchine
- 每一个请求被单独处理
- 请求和请求间任何时间都是隔离的
- 各状态引擎有相关性,通过return连接
- 內建VCL code一直有效,并附加在自建的代码之后(vcl.show -v boot)
三类主要语法
- sub subroutine {
...
}
- if CONDITION {
...
} else {
...
}
- return(), hash_data()
内建函数
regsub(str,regex,sub):字符串为str,根据正则regex模式匹配,把匹配到的内容替换为sub,只替换一次
regsuball(str,regex,sub):和regsub相同,替换所有
ban(boolean expression):符合表达式的都清理
hash_data(input):对input做hash计算
synthetic(str)
hash_data():指明哈希计算的数据;减少差异,以提升命中率
regsub(str,regex,sub):把str中被regex第一次匹配到字符串替换为sub;主要用于URL Rewrite
regsuball(str,regex,sub):把str中被regex每一次匹配到字符串均替换为sub
return()
ban(expression)
ban_url(regex):Bans所有的其URL可以被此处的regex匹配到的缓存对象
synth(status,"STRING"):生成响应报文
Keywords
call subroutine:调用子例行程序
return(action):指明下一个动作
new
set:设定变量的值
unset:取消变量的值
布尔型表达式操作符
==,!=,~,>,>=,<,<=
逻辑操作符:&&,||,!
变量赋值:=
示例:obj.hits是内建变量,用于保存某缓存项从缓存中命中的次数
# vim /etc/varnish/varnish.params
VARNISH_LISTEN_PORT=6081 #监听端口默认是监听在本机的所有低智商的端口
# vim /etc/varnish/default.vcl
backend default {
.host = "192.168.130.10"; #后端服务器的地址
.port = ""; #后端服务器的端口号
}
sub vcl_deliver { #
if (obj.hits>) {
set resp.http.X-Cache = "HIT via" + " " + server.ip;
} else {
set resp.http.X-Cache = "MISS from " + server.ip;
}
}
# systemctl restart varnish #谨慎重启varnish服务,会导致之前的缓存失效
#yum install httpd #在后端安装
#systemctl start http #启动服务
# echo X-Cache > /var/www/html/index.html #在后端服务器上添加页面
# for i in {..};do curl -I -s 192.168.130.8: | grep "X-Cache"; done #在客户端访问
X-Cache: MISS from192.168.130.
X-Cache: HTT via 192.168.130.8
X-Cache: HTT via 192.168.130.8
X-Cache: HTT via 192.168.130.8
X-Cache: HTT via 192.168.130.8
变量类型
示例: 强制对某类资源的请求不检查缓存
# vim /etc/varnish/default.vcl
sub vcl_recv {
if (req.url ~ "(?i)^/(login|admin)") { #"?i"表示忽略大小写,匹配到url中带有login或admin的不查询缓存
return(pass);
}
}
# varnish_reload_vcl
# for i in {..};do curl -I -s 192.168.130.8:/login | grep "X-Cache"; done #在客户端访问/login全部MISS
X-Cache: MISS from192.168.130.
X-Cache: MISS from192.168.130.
X-Cache: MISS from192.168.130.
X-Cache: MISS from192.168.130.
X-Cache: MISS from192.168.130.
# for i in {..};do curl -I -s 192.168.130.8:/admin | grep "X-Cache"; done #在客户端访问/admin全部MISS
X-Cache: MISS from192.168.130.
X-Cache: MISS from192.168.130.
X-Cache: MISS from192.168.130.
X-Cache: MISS from192.168.130.
X-Cache: MISS from192.168.130.
# for i in {..};do curl -I -s 192.168.130.8:/ | grep "X-Cache"; done #在客户端访问其他页面正常缓存查询
X-Cache: MISS from192.168.130.
X-Cache: HTT via 192.168.130.8
X-Cache: HTT via 192.168.130.8
X-Cache: HTT via 192.168.130.8
X-Cache: HTT via 192.168.130.8
示例:对于特定类型的资源,例如公开的图片等,取消其私有标识,并强行设定其可以由varnish缓存的时长
sub vcl_backend_response {
if (beresp.http.cache-control !~ "s-maxage") {
if (bereq.url ~ "(?i)\.(jpg|jpeg|png|gif|css|js)$") {
unset beresp.http.Set-Cookie;
set beresp.ttl = 3600s;
}
}
}
示例:在报文首部添加真正的客户端IP,使得后端server可以记录真正客户端来源
# vim /etc/varnish/default.vcl
sub vcl_recv {
if (req.restarts == ) { #匹配没有被重写的URL请求,即第一次请求
if (req.http.X-Forwarded-For) { #变量存在并且有值则为真
set req.http.X-Forwarded-For = req.http.X-Forwarded-For + "," + client.ip; #将真正的client.ip添加到此变量中,用","隔开
} else {
set req.http.X-Forwarded-For = client.ip; #如果变量不存在或值为空,则直接将client.ip赋值与
}
}
}
# varnishadm -S /etc/varnish/secret -T 127.0.0.1:
varnish> vcl.load conf1 /etc/varnish/default.vcl
varnish> vcl.use conf1
varnish> vcl.list
available boot
available reload_2018--14T09::
active conf1 #当前正在使用的配置
[root@web ~]# vim /etc/httpd/conf/httpd.conf
LogFormat "%{X-Forwarded-For}i %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined
[root@web ~]# systemctl restart httpd
[root@client ~]# for i in {..}; do curl -I -s http://192.168.130.8:6081/admin |grep "X-Cache"; done #在客户端访问
X-Cache: MISS from192.168.130.
X-Cache: HTT via 192.168.130.8
X-Cache: HTT via 192.168.130.8
X-Cache: HTT via 192.168.130.8
X-Cache: HTT via 192.168.130.8
[root@web ~]# tail /var/log/httpd/access_log
192.168.130.8 - - [/Jul/::: +] "HEAD /login HTTP/1.1" - "-" "curl/7.29.0"
192.168.130.8 - - [/Jul/::: +] "HEAD /login HTTP/1.1" - "-" "curl/7.29.0"
192.168.130.8 - - [/Jul/::: +] "HEAD /login HTTP/1.1" - "-" "curl/7.29.0"
192.168.130.8 - - [/Jul/::: +] "HEAD /admin HTTP/1.1" - "-" "curl/7.29.0"
192.168.130.8 - - [/Jul/::: +] "HEAD /admin HTTP/1.1" - "-" "curl/7.29.0"
192.168.130.8 - - [/Jul/::: +] "HEAD /admin HTTP/1.1" - "-" "curl/7.29.0"
192.168.130.8 - - [/Jul/::: +] "HEAD /admin HTTP/1.1" - "-" "curl/7.29.0"
192.168.130.8 - - [/Jul/::: +] "HEAD /admin HTTP/1.1" - "-" "curl/7.29.0"
192.168.130.8 - - [/Jul/::: +] "GET / HTTP/1.1" "-" "curl/7.29.0"
192.168.130.7,192.168.130.7 - - [/Jul/::: +] "GET /admin HTTP/1.1" "-" "curl/7.29.0"#拿到了真正客户端IP,而不是之前的varnish服务器的IP
示例:访问控制,拒绝curl客户端的访问
sub vcl_recv {
if(req.http.User-Agent ~ "curl") {
return(synth());
}
}
缓存对象的修剪:purge
一般在发布新版的内容时需要将缓存清零,然后重新加载新的缓存。
1) 能执行purge操作
sub vcl_purge {
return (synth(,"Purged"));
}
2) 何时执行purge操作
sub vcl_recv {
if (req.method == "PURGE") {
return(purge);
}
...
}
示例:清除指定缓存
# vim /etc/varnish/default.vcl
acl purgers {
"127.0.0.0"/;
"192.168.0.0"/;
}
sub vcl_recv {
if (req.method == "PURGE") {
if (!client.ip ~ purgers) {
return(synth(,"Purging not allowed for " + client.ip));
}
return(purge);
}
}
varnish> vcl.load conf3 /etc/varnish/default.vcl
varnish> vcl.use conf3
[root@client ~]# curl -I http://192.168.130.8:6081/
HTTP/1.1 OK
Date: Sun, Jul :: GMT
Server: Apache/2.4. (CentOS)
Last-Modified: Sun, Jul :: GMT
ETag: "8-57105141f79f4"
Content-Length:
Content-Type: text/html; charset=UTF-
X-Varnish:
Age:
Via: 1.1 varnish-v4
X-Cache: HTT via 192.168.130.8 #从缓存中获取
Connection: keep-alive
[root@client ~]# curl -I -X "PURGE" http://192.168.130.8:6081/ #清除缓存
HTTP/1.1 405 Purging not allowed for 192.168.130.7 #客户端IP
Date: Sun, Jul :: GMT
Server: Varnish
X-Varnish:
Content-Type: text/html; charset=utf-
Retry-After:
Content-Length:
Connection: keep-alive
[root@client ~]# curl -I http://192.168.130.8:6081/
HTTP/1.1 OK
Date: Sun, Jul :: GMT
Server: Apache/2.4. (CentOS)
Last-Modified: Sun, Jul :: GMT
ETag: "8-57105141f79f4"
Content-Length:
Content-Type: text/html; charset=UTF-
X-Varnish:
Age:
Via: 1.1 varnish-v4
X-Cache: MISS from192.168.130.8 #不从缓存中获取
Connection: keep-alive
缓存对象的修剪:Banning
1)varnishadm: ban <field> <operator> <arg>
varnish> ban req.url ~ (?i)^/javascripts
2)在配置文件中定义,使用ban()函数
sub vcl_recv {
if (req.method == "BAN") {
ban("req.http.host == " + req.http.host + " && req.url == " + req.url); #将规则拼接起来传递给ban函数
return(synth(, "Ban added"));
}
}
# curl -I -X "BAN" http://192.168.130.8:6081/javascripts/
多个后端主机实现调度功能
1、动静分离示例:
backend default {
.host = "172.20.81.10";
.port = "";
}
backend appsrv {
.host = "172.20.81.11";
.port = "";
}
sub vcl_recv {
if (req.url ~ "(?i)\.php$") {
set req.backend_hint = appsrv;
} else {
set req.backend_hint = default;
}
}
2、轮询调度
import directors;
backend srv1 {
.host = "192.168.130.10";
.port = "";
}
backend srv2 {
.host = "192.168.130.11";
.port = "";
}
sub vcl_init {
new websrvs = directors.round_robin(); #round_robin()调度算法,不支持加权
websrvs.add_backend(srv1);
websrvs.add_backend(srv2);
}
sub vcl_recv {
set req.backend_hint = websrvs.backend();
}
3、基于cookie的session sticky
sub vcl_init {
new h = directors.hash();
h.add_backend(one, );
h.add_backend(two, );
}
sub vcl_recv {
set req.backend_hint = h.backend(req.http.cookie);
}
4、随机调度,支持权重
sub vcl_init {
new websrvs = directors.random();
websrvs.add_backend(srv1, );
websrvs.add_backend(srv2, );
}
5、后端健康检查
.probe:定义健康状态检测方法;
.url:检测时要请求的URL,默认为”/";
.request:发出的具体请求;
.request =
"GET /.healthtest.html HTTP/1.1"
"Host: www.dongfei.tech"
"Connection: close"
.window:基于最近的多少次检查来判断其健康状态;
.threshold:最近.window中定义的这么次检查中至有.threshhold定义的次数是成功的;
.interval:检测频度;
.timeout:超时时长;
.expected_response:期望的响应码,默认为200;
import directors;
probe http_chk {
.url = "/index.html";
.interval = 2s;
.timeout = 2s;
.window = ; #最近10次检查
.threshold = ; #有7次成功则为健康主机
}
backend srv1 {
.host = "192.168.130.10";
.port = "";
.probe = http_chk;
}
backend srv2 {
.host = "192.168.130.11";
.port = "";
.probe = http_chk;
}
sub vcl_init {
new websrvs = directors.random();
websrvs.add_backend(srv1, );
websrvs.add_backend(srv2, );
}
sub vcl_recv {
set req.backend_hint = websrvs.backend();
}
varnish> backend.list #查看后端主机健康状态信息
Backend name Refs Admin Probe
srv1(192.168.0.9,,) probe Healthy /
srv2(192.168.0.10,,) probe Healthy /
varnish> backend.set_health srv1 sick|healthy|auto #手动标记主机状态 down|up|probe
设置后端的主机属性:
backend BE_NAME {
...
.connect_timeout = .5s; #连接超时时间
.first_byte_timeout = 20s; #第一个字节20s不响应则为超时
.between_bytes_timeout = 5s; #第一个字节和第二个字节间隔超时时间
.max_connections = ; #最大连接数
}
varnish的运行时参数
最大并发连接数 = thread_pools * thread_pool_max
thread_pools:工作线程数,最好小于或等于CPU核心数量
thread_pool_max:每线程池的最大线程数
thread_pool_min:最大空闲线程数
thread_pool_timeout:空闲超过多长时间被清除
thread_pool_add_delay:生成线程之前等待的时间
thread_pool_destroy_delay:清除超出最大空闲线程数的线程之前等待的时间
日志管理
virnish的日志默认存储在80M的内存空间中,如果日志记录超出了则覆盖前边的日志,服务器重启后丢失;需要更改配置使其永久保存到磁盘
# varnishstat - -f MAIN #指定查看MAIN段的信息
# varnishstat - -f MAIN.cache_hit -f MAIN.cache_miss #显示指定参数的当前统计数据
MAIN.cache_hit 0.00 Cache hits
MAIN.cache_miss 0.01 Cache misses
将日志永久保存到:/var/log/varnish/varnish.log
# systemctl start varnishlog.service
varnish web cache服务的更多相关文章
- web cache server方案比较:varnish、squid、nginx
linux运维中,web cache server方案的部署是一个很重要的环节,选择也有很多种比如:varnish.squid.nginx.下面就对当下常用的这几个web cache server做一 ...
- varnish页面缓存服务
varnish页面缓存服务 https://www.cnblogs.com/L-dongf/p/9310144.html http://blog.51cto.com/xinzong/1782669 阅 ...
- 七、Nginx学习笔记七Nginx的Web缓存服务
user www; worker_processes 1; error_log /usr/local/nginx/logs/error.log crit; pid /usr/local/nginx/l ...
- nginx的web缓存服务环境部署记录
web缓存位于内容源Web服务器和客户端之间,当用户访问一个URL时,Web缓存服务器会去后端Web源服务器取回要输出的内容,然后,当下一个请求到来时,如果访问的是相同的URL,Web缓存服务器直接输 ...
- CDN之Web Cache
1. Cache 的工作方式 Web Cache 作为一种网页缓存技术,可以在用户访问网站服务器的任何一个中间网元上实现.根据 HTTP 协议的定义,在一次网页访问中,用户从客户端发出请求到网站服务器 ...
- 使用axis开发web service服务端
一.axis环境搭建 1.安装环境 JDK.Tomcat或Resin.eclipse等. 2.到 http://www.apache.org/dyn/closer.cgi/ws/axis/1_4下载A ...
- Web Serveice服务代理类生成及编译
本文链接地址:http://www.cnblogs.com/dengxinglin/p/3334158.html 一.生成代理类 对于web service服务和wcf的webservice服务,我们 ...
- 使用Eclipse自带Web Service插件(Axis1.4)生成Web Service服务端/客户端
创建一个名字为math的Java web工程,并将WSDL文件拷入该工程中 将Axis所需的jar包拷贝至WebRoot\WEB-INF\lib目录下,这些jar包会自动导入math工程中 一,生成W ...
- SharePoint咨询师之路:备份和恢复系列三 - 备份web和服务应用程序
本系列包括: 备份服务器场和配置 备份web和服务应用程序 备份内容数据库 备份网站集 备份自定义项 备份web应用程序和服务应用程序一样有三种方式:SharePoint管理中心网站.Windows ...
随机推荐
- 三:后台的登录注册接口(moon项目,前面有一,二)
** 项目一共有 16 个页面,是一个电商网销项目,自己在网上的某网上找的一个要做的网站的设计图: 页面主要包括: 登录页 -- 注册页 -- 首页 -- 产品列表页 -- 产品详情页 -- 会员中 ...
- 使用vue国际化中出现内置的组件无法切换语言的问题(element-ui、ivew)
在main.js中引入对应组件的语言包 eg: import VueI18n from 'vue-i18n'; // 引入国际化 import elementEn from 'element-ui/l ...
- python多线程与多进程异步事件框架
多线程简单实现 #!/usr/bin/env python # -*- coding: UTF-8 -*- import logging import queue import threading f ...
- Trie 树(字典树)
[动画]看动画轻松理解「Trie树」 读音 Trie这个名字取自“retrieval”,检索,因为Trie可以只用一个前缀便可以在一部字典中找到想要的单词. 虽然发音与「Tree」一致,但为了将这种 ...
- MySQL增量备份与恢复实例
小量的数据库可以每天进行完整备份,因为这也用不了多少时间,但当数据库很大时,就不太可能每天进行一次完整备份了,这时候就可以使用增量备份.增量备份的原理就是使用了mysql的binlog日志. 本次操作 ...
- Image Processing and Analysis_15_Image Registration:A survey of medical image registration——1998
此主要讨论图像处理与分析.虽然计算机视觉部分的有些内容比如特 征提取等也可以归结到图像分析中来,但鉴于它们与计算机视觉的紧密联系,以 及它们的出处,没有把它们纳入到图像处理与分析中来.同样,这里面也有 ...
- 创建守护进程步骤与setsid()
原创:http://www.cnblogs.com/mickole/p/3188321.html 一,守护进程概述 Linux Daemon(守护进程)是运行在后台的一种特殊进程.它独立于控制终端并且 ...
- Ubuntu系统---C++之Eclipse编译器 CDT插件安装
Ubuntu系统---Ecli ...
- 作业十一——LL(1)文法的判断
1. 文法 G(S): (1)S -> AB (2)A ->Da|ε (3)B -> cC (4)C -> aADC |ε (5)D -> b|ε 验证文法 G(S)是不 ...
- mysql 数据库的相关操作
#coding=gbk #数据库的连接语句 import pymysql try: conn=pymysql.connect( host='127.0.0.1', port=3306, user='r ...