热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

Varnish服务器的安装和维护

各文档所在位置日志文件/var/log/varnish/varnish.log可执行程序/usr/local/varnish/bin缓冲文件/var/vcache配置文件/usr/local/varnish/vcl.conf启动参数/etc/sysconfig/varnish启动脚本/etc/rc.d/init.d/v


各文档所在位置
日志文件 /var/log/varnish/varnish.log
可执行程序 /usr/local/varnish/bin
缓冲文件 /var/vcache
配置文件 /usr/local/varnish/vcl.conf
启动参数 /etc/sysconfig/varnish
启动脚本 /etc/rc.d/init.d/varnish
/etc/rc.d/init.d/varnishlog

创建www用户和组,以及Varnish缓存文件存放目录(/var/vcache):
/usr/sbin/groupadd www -g 48
/usr/sbin/useradd -u 48 -g www www
mkdir -p /var/vcache
chmod +w /var/vcache
chown -R www:www /var/vcache

创建日志文件,并授予www用户权限访问
mkdir -p /var/log/varnish
chmod +w /var/log/varnish
chown -R www:www /var/log/varnish

可能需要安装如下包
[CENTOS]yum install ncurses-devel
[UBUNTU]apt-get install libncurses5-dev

编译安装
./configure ?prefix=/usr/local/varnish
make
make install

编辑配置文件
vi /usr/local/varnish/vcl.conf
view plaincopy to clipboardprint?
backend myblogserver {
set backend.host = “192.168.0.5″;
set backend.port = “80″;
}

acl purge {
“localhost”;
“127.0.0.1″;
“192.168.1.0″/24;
}

sub vcl_recv {
if (req.request == “PURGE”) {
if (!client.ip ~ purge) {
error 405 “Not allowed.”;
}
lookup;
}

if (req.http.host ~ “^www.hiadmin.com”) {
set req.backend = myblogserver;
if (req.request != “GET” && req.request != “HEAD”) {
pipe;
}
elseif(req.url ~ “/.(php|cgi)($|/?)”) {
pass;
}
else {
lookup;
}
}
else {
error 404 “Cache Server”;
lookup;
}
}

sub vcl_hit {
if (req.request == “PURGE”) {
set obj.ttl = 0s;
error 200 “Purged.”;
}
}

sub vcl_miss {
if (req.request == “PURGE”) {
error 404 “Not in cache.”;
}
}

sub vcl_fetch {
if (req.request == “GET” && req.url ~ “/.(txt|js)$”) {
set obj.ttl = 3600s;
}
else {
set obj.ttl = 30d;
}
}

backend myblogserver {
set backend.host = “192.168.0.5″;
set backend.port = “80″;
}

acl purge {
“localhost”;
“127.0.0.1″;
“192.168.1.0″/24;
}

sub vcl_recv {
if (req.request == “PURGE”) {
if (!client.ip ~ purge) {
error 405 “Not allowed.”;
}
lookup;
}

if (req.http.host ~ “^www.hiadmin.com”) {
set req.backend = myblogserver;
if (req.request != “GET” && req.request != “HEAD”) {
pipe;
}
elseif(req.url ~ “/.(php|cgi)($|/?)”) {
pass;
}
else {
lookup;
}
}
else {
error 404 “Cache Server”;
lookup;
}
}

sub vcl_hit {
if (req.request == “PURGE”) {
set obj.ttl = 0s;
error 200 “Purged.”;
}
}

sub vcl_miss {
if (req.request == “PURGE”) {
error 404 “Not in cache.”;
}
}

sub vcl_fetch {
if (req.request == “GET” && req.url ~ “/.(txt|js)$”) {
set obj.ttl = 3600s;
}
else {
set obj.ttl = 30d;
}
}

启动varnish
ulimit -SHn 51200
/usr/local/varnish/sbin/varnishd -n /var/vcache -f /usr/local/varnish/vcl.conf -a 0.0.0.0:80 -s file,/var/vcache/varnish_cache.data,1G -g www -u www -w 30000,51200,10 -T 127.0.0.1:3500 -p client_http11=on

启动varnishncsa记录访问日志
/usr/local/varnish/bin/varnishncsa -n /var/vcache -w /var/log/varnish/varnish.log &

优化linux内核
vi /etc/sysctl.conf
添加以下内容
view plaincopy to clipboardprint?
net.ipv4.tcp_fin_timeout = 30
net.ipv4.tcp_keepalive_time = 300
net.ipv4.tcp_synCOOKIEs = 1
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_tw_recycle = 1
net.ipv4.ip_local_port_range = 5000 65000

net.ipv4.tcp_fin_timeout = 30
net.ipv4.tcp_keepalive_time = 300
net.ipv4.tcp_synCOOKIEs = 1
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_tw_recycle = 1
net.ipv4.ip_local_port_range = 5000 65000

执行优化
sysctl -p

编辑varnish启动参数
# vi /etc/sysconfig/varnish
修改

# Configuration file for varnish   
#   
# /etc/init.d/varnish expects the variable $DAEMON_OPTS to be set from this   
# shell script fragment.   
#   
# Maximum number of open files (for ulimit -n)   
NFILES=131072   
# # Main configuration file. You probably want to change it :)   
VARNISH_VCL_COnF=/usr/local/varnish/vcl.conf   
#   
# # Default address and port to bind to   
# # Blank address means all IPv4 and IPv6 interfaces, otherwise specify   
# # a host name, an IPv4 dotted quad, or an IPv6 address in brackets.   
# VARNISH_LISTEN_ADDRESS=80   
VARNISH_LISTEN_PORT=80   
#   
# # Telnet admin interface listen address and port   
VARNISH_ADMIN_LISTEN_ADDRESS=127.0.0.1   
VARNISH_ADMIN_LISTEN_PORT=6082   
#   
# # The minimum number of worker threads to start   
VARNISH_MIN_THREADS=1   
#   
# # The Maximum number of worker threads to start   
VARNISH_MAX_THREADS=1000   
#   
# # Idle timeout for worker threads   
VARNISH_THREAD_TIMEOUT=120   
#   
# # Cache file location   
VARNISH_STORAGE_FILE=/var/vcache/varnish_cache.data  #   
# # Cache Directory   
VARNISH_WORKDIR=/var/vcache   
#   
# # Cache file size: in bytes, optionally using k / M / G / T suffix,   
# # or in percentage of available disk space using the % suffix.   
VARNISH_STORAGE_SIZE=2G   
#   
# # Backend storage specification   
VARNISH_STORAGE="file,${VARNISH_STORAGE_FILE},${VARNISH_STORAGE_SIZE}" 
#   
# # Default TTL used when the backend does not specify one  VARNISH_TTL=120   
# # varnish run as   
VARNISH_USER=www   
VARNISH_GROUP=www   
#   
# # DAEMON_OPTS is used by the init script.  If you add or remove options, make   
# # sure you update this section, too.   
 DAEMON_OPTS="-a ${VARNISH_LISTEN_ADDRESS}:${VARNISH_LISTEN_PORT} /   
              -f ${VARNISH_VCL_CONF} /   
              -T ${VARNISH_ADMIN_LISTEN_ADDRESS}:${VARNISH_ADMIN_LISTEN_PORT} /   
              -t ${VARNISH_TTL} /   
              -w ${VARNISH_MIN_THREADS},${VARNISH_MAX_THREADS},${VARNISH_THREAD_TIMEOUT} /   
              -u ${VARNISH_USER} -g ${VARNISH_GROUP} /   
              -n ${VARNISH_WORKDIR} /   
              -s ${VARNISH_STORAGE}"   

# Configuration file for varnish
#
# /etc/init.d/varnish expects the variable $DAEMON_OPTS to be set from this
# shell script fragment.
#

# Maximum number of open files (for ulimit -n)
NFILES=131072

# # Main configuration file. You probably want to change it :)
VARNISH_VCL_COnF=/usr/local/varnish/vcl.conf
#
# # Default address and port to bind to
# # Blank address means all IPv4 and IPv6 interfaces, otherwise specify
# # a host name, an IPv4 dotted quad, or an IPv6 address in brackets.
# VARNISH_LISTEN_ADDRESS=80
VARNISH_LISTEN_PORT=80
#
# # Telnet admin interface listen address and port
VARNISH_ADMIN_LISTEN_ADDRESS=127.0.0.1
VARNISH_ADMIN_LISTEN_PORT=6082
#
# # The minimum number of worker threads to start
VARNISH_MIN_THREADS=1
#
# # The Maximum number of worker threads to start
VARNISH_MAX_THREADS=1000
#
# # Idle timeout for worker threads
VARNISH_THREAD_TIMEOUT=120
#
# # Cache file location
VARNISH_STORAGE_FILE=/var/vcache/varnish_cache.data
#
# # Cache Directory
VARNISH_WORKDIR=/var/vcache
#
# # Cache file size: in bytes, optionally using k / M / G / T suffix,
# # or in percentage of available disk space using the % suffix.
VARNISH_STORAGE_SIZE=2G
#
# # Backend storage specification
VARNISH_STORAGE="file,${VARNISH_STORAGE_FILE},${VARNISH_STORAGE_SIZE}"
#
# # Default TTL used when the backend does not specify one
VARNISH_TTL=120
# # varnish run as
VARNISH_USER=www
VARNISH_GROUP=www
#
# # DAEMON_OPTS is used by the init script.  If you add or remove options, make
# # sure you update this section, too.
 DAEMON_OPTS="-a ${VARNISH_LISTEN_ADDRESS}:${VARNISH_LISTEN_PORT} /
              -f ${VARNISH_VCL_CONF} /
              -T ${VARNISH_ADMIN_LISTEN_ADDRESS}:${VARNISH_ADMIN_LISTEN_PORT} /
              -t ${VARNISH_TTL} /
              -w ${VARNISH_MIN_THREADS},${VARNISH_MAX_THREADS},${VARNISH_THREAD_TIMEOUT} /
              -u ${VARNISH_USER} -g ${VARNISH_GROUP} /
              -n ${VARNISH_WORKDIR} /
              -s ${VARNISH_STORAGE}"
#

配置启动脚本
# vi $home/varnish-1.1.2/redhat/varnish.initrc
修改
DAEMON=”/usr/local/varnish/sbin/varnishd”
# cp varnishlog.initrc /etc/rc.d/init.d/varnish

配置varnishlog启动脚本
# vi $home/varnish-1.1.2/redhat/varnishlog.initrc
修改
DAEMON=”/usr/local/varnish/bin/varnishlog”
LOGFILE=”/var/log/varnish/varnish.log”
CACHEFILE=”/var/vcache”
DAEMON_OPTS=”-a -n ${CACHEFILE} -w ${LOGFILE} -D -P $PIDFILE”
# chmod 755 varnishlog.initrc
# cp varnishlog.initrc /etc/rc.d/init.d/varnishlog

启动varnish
/etc/rc.d/init.d/varnish start
/etc/rc.d/init.d/varnishlog start

查看varnish状态
/usr/local/varnish/bin/varnishstat -n /var/vcache

通过varnish管理端口进行管理
/usr/local/varnish/bin/varnishadm -T 127.0.0.1:3500

通过正则清楚缓存
/usr/local/varnish/bin/varnishadm -T 127.0.0.1:3500 url.purge 正则表达式

/*附录摘自leftleg.hzpub.com*/
*********************************************************************************************
man page意译如下:

VCL语法比较简单,和C类似,if(){}的形式,=和==的区别,!、&&和||等等。但/符号没有特别的意思。
VCL里除了用==、!、&&、||做逻辑判断意外,还可以用~来表示与正则表达式或ACL的匹配。
VCL其实只是配置,并不是真正的编程语言,没有循环,没有自定义变量。

声明Backend
backend 名称 {
set backend.host = “域名”;
set backend.port = “端口”;
}
比如
backend www {
set backend.host = “www.example.com”;
set backend.port = “http”;
}
声明的Backend可以用在判断请求针对哪个后端服务器
if (req.http.host ~ “^(www.)?example.com$”) {
{
set req.backend = www;
}

声明ACL
acl 名称 {
“IP”;
“IP子网”/反掩码位数;
! “IP或IP子网”/反掩码位数;
}
比如
acl local {
“locahost”; /* myself */
“10.0.0.1″/8; /* and everyone on the local network */
! “10.0.0.23″; /* except for the dialin router */
}
判断ACL也很简单
if (client.ip ~ local) {
pipe;
}

还可以定义子程序
sub pipe_if_local {
if (client.ip ~ local) {
pipe;
}
}
用call来调用
call pipe_if_local;

内置的例程
vcl_recv
有请求到达后成功接收并分析时被调用,一般以以下几个关键字结束。
error code [reason] 返回code给客户端,并放弃处理该请求
pass 进入pass模式,把控制权交给vcl_pass
pipe 进入pipe模式,把控制权交给vcl_pipe
lookup 在缓存里查找被请求的对象,根据查找结果把控制权交给vcl_hit或vcl_miss

vcl_pipe
进入pipe模式时被调用。请求被直接发送到backend,后端和客户端之间的后继数据不进行处理,只是简单传递,直到一方关闭连接。一般以以下几个关键字结束。
error code [reason]
pipe

vcl_pass
进入pass模式时被调用。请求被送到后端,后端应答数据送给客户端,但不进入缓存。同一连接的后继请求正常处理。一般以以下几个关键字结束。
error code [reason]
pass

vcl_hash
目前不使用

vcl_hit
在lookup以后如果在cache中找到请求的内容事调用。一般以以下几个关键字结束。
error code [reason]
pass
deliver 将找到的内容发送给客户端,把控制权交给vcl_deliver.

vcl_miss
lookup后但没有找到缓存内容时调用,可以用于判断是否需要从后端服务器取内容。一般以以下几个关键字结束。
error code [reason]
pass
fetch 从后端取得请求的内容,把控制权交给vcl_fetch.

vcl_fetch
从后端取得内容后调用。一般以以下几个关键字结束。
error code [reason]
pass
insert 将取到的内容插入缓存,然后发送给客户端,把控制权交给vcl_deliver

vcl_deliver
缓存内容发动给客户端前调用。一般以以下几个关键字结束。
error code [reason]
deliver 内容发送给客户端

vcl_timeout
在缓存内容到期前调用。一般以以下几个关键字结束。
fetch 从后端取得该内容
discard 丢弃该内容

vcl_discard
由于到期或者空间不足而丢弃缓存内容时调用。一般以以下几个关键字结束。
discard 丢弃
keep 继续保留在缓存里

如果这些内置例程没有被定义,则执行缺省动作

一些内置的变量
now 当前时间,标准时间点(1970?)到现在的秒数

backend.host 后端的IP或主机名
backend.port 后端的服务名或端口

请求到达后有效的变量
client.ip 客户端IP
server.ip 服务端IP
req.request 请求类型,比如GET或者HEAD或者POST
req.url 请求的URL
req.proto 请求的HTTP版本号
req.backend 请求对应的后端
req.http.header 对应的HTTP头

往后段的请求时有效的变量
bereq.request 比如GET或HEAD
bereq.url URL
bereq.proto 协议版本
bereq.http.header HTTP头

从cache或后端取到内容后有效的变量
obj.proto HTTP协议版本
obj.status HTTP状态代码
obj.response HTTP状态信息
obj.valid 是否有效的HTTP应答
obj.cacheable 是否可以缓存的内容,也就是说如果HTTP返回是200、203、300、301、302、404、410并且有非0的生存期,则为可缓存
obj.ttl 生存期,秒
obj.lastuse 上一次请求到现在间隔秒数

对客户端应答时有效的变量
resp.proto response的HTTP版本
resp.status 回给客户端的HTTP状态代码
resp.response 回给客户端的HTTP状态信息
resp.http.header HTTP头

变量可以通过set来赋值或通过remove来删除(清空)
sub vcl_recv {
if (req.http.host ~ “^(www.)?example.com$”) {
set req.http.host = “www.example.com”;
}
}

sub vcl_fetch {
remove obj.http.Set-COOKIE;
}

##########关于varnishd的启动
进入 /home/admin/varnishd/sbin/,使用 varnishd启动
启动参数说明
-a address:port # varnishd httpd监听地址及其端口
-b address:port # 后台服务器地址及其端口
# -b
# -b ‘:’
-d # 使用debug模式
-f file # varnishd 服务器存取规则文件
-F # Run in foreground
-h kind[,hashoptions] # Hash specification
# -h simple_list
# -h classic [default]
# -h classic,
-n dir # varnishd working directory
-P file # PID file
-p param=value # 服务器参数,用来优化性能
-s kind[,storageoptions] # 缓存内容存放方式
# -s malloc
# -s file [default: use /tmp]
# -s file,
# -s file,,
-t # Default TTL
-T address:port # telnet管理地址及其端口
-V # version
-w int[,int[,int]] # 工作线程数
# -w
# -w min,max
# -w min,max,timeout [default: -w1,1000,120]
一般使用varnishd -a address:port -b address:port 其他使用默认即可启动
注意:vcl 中指定 后台服务器的话就不用使用-b 参数了
4.关于vcl文件的使用说明
vcl是varnishd的存取策略,即varnishd的配置文件
#基本格式如下指定后台服务器机器端口
backend www {
set backend.host = “www.example.com”;
set backend.port = “http”;
}
#acl访问控制
acl local {
“locahost”; /* myself */
“10.0.0.1″/8; /* and everyone on the local network */
! “10.0.0.23″; /* except for the dialin router */
}
#如果使用虚拟主机,请参照下面代码
view plaincopy to clipboardprint?
backend www {
set backend.host = “www.example.com”;
set backend.port = “80″;
}
backend images {
set backend.host = “images.example.com”;
set backend.port = “80″;
}
sub vcl_recv {
if (req.http.host ~ “^(www.)?example.com$”) {
set req.backend = www;
} elsif (req.http.host ~ “^images.example.com”) {
set req.backend = images;
} else {
error 404 “Unknown virtual host”;
}
}

backend www {
set backend.host = “www.example.com”;
set backend.port = “80″;
}
backend images {
set backend.host = “images.example.com”;
set backend.port = “80″;
}
sub vcl_recv {
if (req.http.host ~ “^(www.)?example.com$”) {
set req.backend = www;
} elsif (req.http.host ~ “^images.example.com”) {
set req.backend = images;
} else {
error 404 “Unknown virtual host”;
}
}

#关于cache存在时间设置
sub vcl_fetch {
if (obj.ttl <120s) {
set obj.ttl = 120s;
}
}
#cache图片等内容配置
sub vcl_recv {
if (req.request == “GET” && req.url ~ “/.(gif|jpg||jpeg|tom|swf|css|js)$”) {
lookup;
}
lookup;
}
##########关于vcl文件的使用说明
vcl是varnishd的存取策略,即varnishd的配置文件
#基本格式如下指定后台服务器机器端口
backend www {
set backend.host = “www.example.com”;
set backend.port = “http”;
}
#acl访问控制
acl local {
“locahost”; /* myself */
“10.0.0.1″/8; /* and everyone on the local network */
! “10.0.0.23″; /* except for the dialin router */
}
#如果使用虚拟主机,请参照下面代码
backend www {
set backend.host = “www.example.com”;
set backend.port = “80″;
}
backend images {
set backend.host = “images.example.com”;
set backend.port = “80″;
}
sub vcl_recv {
if (req.http.host ~ “^(www.)?example.com$”) {
set req.backend = www;
} elsif (req.http.host ~ “^images.example.com”) {
set req.backend = images;
} else {
error 404 “Unknown virtual host”;
}
}
#关于cache存在时间设置
sub vcl_fetch {
if (obj.ttl <120s) {
set obj.ttl = 120s;
}
}
#cache图片等内容配置
sub vcl_recv {
if (req.request == “GET” && req.url ~ “/.(gif|jpg||jpeg|tom|swf|css|js)$”) {
lookup;
}
lookup;
}
########## 关于服务器 param的设置
param有以下选项
user root (0)
group root (0)
default_ttl 14400 [seconds]
thread_pools 1 [pools]
thread_pool_max 12000 [threads]
thread_pool_min 4000 [threads]
thread_pool_timeout 10 [seconds]
overflow_max 100 [%]
http_workspace 8192 [bytes]
sess_timeout 5 [seconds]
pipe_timeout 60 [seconds]
send_timeout 20 [seconds]
auto_restart on [bool]
fetch_chunksize 128 [kilobytes]
sendfile_threshold unlimited [bytes]
vcl_trace off [bool]
listen_address 172.16.189.1:3128
listen_depth 1024 [connections]
srcaddr_hash 1049 [buckets]
srcaddr_ttl 720 [seconds]
backend_http11 on [bool]
client_http11 on [bool]
ping_interval 3 [seconds]
大家可以使用-p参数在启动时候进行配置和优化
例如
/home/admin/varnish/sbin/varnishd -f /etc/varnish/vcl.conf /
-a 172.16.189.1:3128 /
-s malloc /
-p user root -p group root /
-p default_ttl 14400 -p thread_pool_max 8000 -p send_timeout 20 /
-p srcaddr_ttl 720 -p backend_http11 on -p client_http11 on /
-w 4000,12000,10 -T 127.0.0.1:8080

########## 关于varnishd的管理
管理功能的启用需要在启动varnishd的时候 启动 -T参数指定 telnet管理使用的地址和端口
使用telnet localhost 8080,然后输入help参看相关的管理选项
或者使用 /home/admin/varnishd/bin/varnishadm -T localhost:8080 cmd进行管理
使用/home/admin/varnishd/bin/varnishstat 来查看varnishd的运行情况

########## 关于log
使用home/admin/varnishd/bin/varnishlog 和varnishncsa查看服务器访问log或者让其输出到文件来记录log


推荐阅读
  • 本文介绍了一款用于自动化部署 Linux 服务的 Bash 脚本。该脚本不仅涵盖了基本的文件复制和目录创建,还处理了系统服务的配置和启动,确保在多种 Linux 发行版上都能顺利运行。 ... [详细]
  • 1:有如下一段程序:packagea.b.c;publicclassTest{privatestaticinti0;publicintgetNext(){return ... [详细]
  • 使用Vultr云服务器和Namesilo域名搭建个人网站
    本文详细介绍了如何通过Vultr云服务器和Namesilo域名搭建一个功能齐全的个人网站,包括购买、配置服务器以及绑定域名的具体步骤。文章还提供了详细的命令行操作指南,帮助读者顺利完成建站过程。 ... [详细]
  • 本文介绍如何通过SSH协议使用Xshell远程连接到Ubuntu系统。为了实现这一目标,需要确保Ubuntu系统已安装并配置好SSH服务器,并保证网络连通性。 ... [详细]
  • 解决U盘安装系统后无法重启的问题
    本文详细探讨了运维新手常遇到的U盘安装系统后无法正常重启的问题,提供了从问题分析到具体解决方案的完整步骤。通过理解Boot Loader的工作原理和正确配置启动项,帮助用户顺利解决问题。 ... [详细]
  • 在计算机技术的学习道路上,51CTO学院以其专业性和专注度给我留下了深刻印象。从2012年接触计算机到2014年开始系统学习网络技术和安全领域,51CTO学院始终是我信赖的学习平台。 ... [详细]
  • 本周信息安全小组主要进行了CTF竞赛相关技能的学习,包括HTML和CSS的基础知识、逆向工程的初步探索以及整数溢出漏洞的学习。此外,还掌握了Linux命令行操作及互联网工作原理的基本概念。 ... [详细]
  • Linux 系统启动故障排除指南:MBR 和 GRUB 问题
    本文详细介绍了 Linux 系统启动过程中常见的 MBR 扇区和 GRUB 引导程序故障及其解决方案,涵盖从备份、模拟故障到恢复的具体步骤。 ... [详细]
  • CentOS7源码编译安装MySQL5.6
    2019独角兽企业重金招聘Python工程师标准一、先在cmake官网下个最新的cmake源码包cmake官网:https:www.cmake.org如此时最新 ... [详细]
  • 本文详细介绍了 Dockerfile 的编写方法及其在网络配置中的应用,涵盖基础指令、镜像构建与发布流程,并深入探讨了 Docker 的默认网络、容器互联及自定义网络的实现。 ... [详细]
  • 本文详细介绍了VMware的多种认证选项,帮助你根据职业需求和个人技能选择最合适的认证路径,涵盖从基础到高级的不同层次认证。 ... [详细]
  • 本文详细介绍了如何在Ubuntu系统中下载适用于Intel处理器的64位版本,涵盖了不同Linux发行版对64位架构的不同命名方式,并提供了具体的下载链接和步骤。 ... [详细]
  • 本文介绍如何通过更改软件源来提前体验Ubuntu 8.10,包括详细的配置步骤和相关注意事项。 ... [详细]
  • 自己用过的一些比较有用的css3新属性【HTML】
    web前端|html教程自己用过的一些比较用的css3新属性web前端-html教程css3刚推出不久,虽然大多数的css3属性在很多流行的浏览器中不支持,但我个人觉得还是要尽量开 ... [详细]
  • PHP 时间与日期工具类:星座、干支、生肖的实现
    本文介绍了一个PHP时间与日期工具类,涵盖了时区设置、有效日期和时间检查、星座、干支、生肖计算等功能。该工具类特别适用于需要处理中国农历及西方星座的应用场景。 ... [详细]
author-avatar
无可奈何花落去
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有