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服务的更多相关文章

  1. web cache server方案比较:varnish、squid、nginx

    linux运维中,web cache server方案的部署是一个很重要的环节,选择也有很多种比如:varnish.squid.nginx.下面就对当下常用的这几个web cache server做一 ...

  2. varnish页面缓存服务

    varnish页面缓存服务 https://www.cnblogs.com/L-dongf/p/9310144.html http://blog.51cto.com/xinzong/1782669 阅 ...

  3. 七、Nginx学习笔记七Nginx的Web缓存服务

    user www; worker_processes 1; error_log /usr/local/nginx/logs/error.log crit; pid /usr/local/nginx/l ...

  4. nginx的web缓存服务环境部署记录

    web缓存位于内容源Web服务器和客户端之间,当用户访问一个URL时,Web缓存服务器会去后端Web源服务器取回要输出的内容,然后,当下一个请求到来时,如果访问的是相同的URL,Web缓存服务器直接输 ...

  5. CDN之Web Cache

    1. Cache 的工作方式 Web Cache 作为一种网页缓存技术,可以在用户访问网站服务器的任何一个中间网元上实现.根据 HTTP 协议的定义,在一次网页访问中,用户从客户端发出请求到网站服务器 ...

  6. 使用axis开发web service服务端

    一.axis环境搭建 1.安装环境 JDK.Tomcat或Resin.eclipse等. 2.到 http://www.apache.org/dyn/closer.cgi/ws/axis/1_4下载A ...

  7. Web Serveice服务代理类生成及编译

    本文链接地址:http://www.cnblogs.com/dengxinglin/p/3334158.html 一.生成代理类 对于web service服务和wcf的webservice服务,我们 ...

  8. 使用Eclipse自带Web Service插件(Axis1.4)生成Web Service服务端/客户端

    创建一个名字为math的Java web工程,并将WSDL文件拷入该工程中 将Axis所需的jar包拷贝至WebRoot\WEB-INF\lib目录下,这些jar包会自动导入math工程中 一,生成W ...

  9. SharePoint咨询师之路:备份和恢复系列三 - 备份web和服务应用程序

    本系列包括: 备份服务器场和配置 备份web和服务应用程序 备份内容数据库 备份网站集 备份自定义项 备份web应用程序和服务应用程序一样有三种方式:SharePoint管理中心网站.Windows  ...

随机推荐

  1. POJ2729 Robocode(离散化与模拟-----提醒曾经爱玩游戏的自己没做出这个

    题目链接 :http://poj.org/problem?id=2729 题目很长,有不少也是废话.类似小时候玩的坦克大战.每个坦克速度为10,炮弹速度为20.子弹出界就消失,坦克出不了界限.相向的子 ...

  2. 阿里云 ecs win2016 FileZilla Server

     Windows Server 2016 下使用 FileZilla Server 安装搭建 FTP 服务 一.安装 Filezilla Server 下载最新版本的 Filezilla Server ...

  3. Personalize Oracle Applications Home Page Browser Window Title

    修改登录页 http://expertoracle.com/2016/03/10/personalizing-the-e-business-suite-r12-login-page/ STEP 2 : ...

  4. BP神经网络—java实现

    神经网络的结构 神经网络的网络结构由输入层,隐含层,输出层组成.隐含层的个数+输出层的个数=神经网络的层数,也就是说神经网络的层数不包括输入层.下面是一个三层的神经网络,包含了两层隐含层,一个输出层. ...

  5. openstack安装部署——计算服务(控制节点&计算节点)前言

    1.前言Openstack计算服务通过认证服务获取认证:通过镜像服务获取镜像:通过仪表盘提供的用户界面与用户交互.镜像的存取受工程和用户的限制,配额受工程的限制(例如不同工程允许虚拟机实例数量不同). ...

  6. 19C imp 导入合并表空间

    因为项目需要从9i 导数据到18C,所以发现如下特性 1.18C imp 导入数据,如果表空间在目标库没有,会将表导入到用户默认表空间 2.18C imp 导入数据,如果表空间在目标库有,但缺少权限. ...

  7. Nginx中location模块的详细配置(含示例)

    题记 此前在配置Nginx location模块的时候玩出了一些bug,折腾了一段时间.后来网上也查阅了相关的资料,看着也比较混乱.周末有空想着好好整理一下location模块的配置,结合自己的亲手实 ...

  8. python实现pow函数(求n次幂,求n次方)

    目录 类型一:求n次幂 类型二:求n开方 类型一:求n次幂 实现 pow(x, n),即计算 x 的 n 次幂函数.其中n为整数.pow函数的实现--leetcode 解法1:暴力法 不是常规意义上的 ...

  9. How Many Answers Are Wrong(带权并查集)

    题目 带权并查集的博客~ 题目: 多组输入数据.n,m.你不知道[1,n]内任意区间内值的和. m次询问,a b 是端点,都在n的范围以内 : v表示 [a,b]的区间内值的和.对每次询问,判断v是否 ...

  10. Why do we name variables in Tensorflow?

    Reference:Stack Overflow. The name parameter is optional (you can create variables and constants wit ...