当前位置: 首页 > 编程日记 > 正文

Memcached 缓存系统的-介绍、安装以及应用

一. memcached 是什么?
memcached is a high-performance, distributed memory object caching system, generic in nature, but intended for use in speeding up dynamic web applications by alleviating database load.
memcached是一个高性能的、分布式内存对象缓存系统,应用广泛。通过缓存数据库查询结果,减少数据库访问次数,以提高动态Web应用的速度、 提高可扩展性。
它可以应对任意多个连接,使用非阻塞的网络IO。由于它的工作机制是在内存中开辟一块空间,然后建立一个HashTable,Memcached自管理这些HashTable。还使用内置的内存块分配和哈希表算法,确保虚拟内存不会过来捣乱。
Memcached 官方网站:http://www.danga.com/memcached

二. memcached 的安装:
注:memcached 用到了libevent这个库用于Socket的处理,所以还需要安装libevent.官网:http://www.monkey.org/~provos/libevent/
1. 先安装libevent:
[root@localhost software]# tar zxvf libevent-1.4.11-stable.tar.gz
[root@localhost libevent-1.4.11-stable]# ./configure –prefix=/usr
[root@localhost libevent-1.4.11-stable]# make
[root@localhost libevent-1.4.11-stable]# make install

2. 测试libevent是否安装成功
[root@localhost libevent-1.4.11-stable]# ls -al /usr/lib | grep libevent
lrwxrwxrwx   1 root root       22 07-10 13:10 libevent-1.1a.so.1 -> libevent-1.1a.so.1.0.2
-rwxr-xr-x   1 root root    31596 2007-01-07 libevent-1.1a.so.1.0.2
lrwxrwxrwx   1 root root       21 07-21 03:33 libevent-1.4.so.2 -> libevent-1.4.so.2.1.3
-rwxr-xr-x   1 root root   308088 07-21 03:33 libevent-1.4.so.2.1.3
-rw-r--r--   1 root root   394474 07-21 03:33 libevent.a
lrwxrwxrwx   1 root root       26 07-21 03:33 libevent_core-1.4.so.2 -> libevent_core-1.4.so.2.1.3
-rwxr-xr-x   1 root root   109490 07-21 03:33 libevent_core-1.4.so.2.1.3
-rw-r--r--   1 root root   148742 07-21 03:33 libevent_core.a
-rwxr-xr-x   1 root root      866 07-21 03:33 libevent_core.la
lrwxrwxrwx   1 root root       26 07-21 03:33 libevent_core.so -> libevent_core-1.4.so.2.1.3
lrwxrwxrwx   1 root root       27 07-21 03:33 libevent_extra-1.4.so.2 -> libevent_extra-1.4.so.2.1.3
-rwxr-xr-x   1 root root   246870 07-21 03:33 libevent_extra-1.4.so.2.1.3
-rw-r--r--   1 root root   307370 07-21 03:33 libevent_extra.a
-rwxr-xr-x   1 root root      873 07-21 03:33 libevent_extra.la
lrwxrwxrwx   1 root root       27 07-21 03:33 libevent_extra.so -> libevent_extra-1.4.so.2.1.3
-rwxr-xr-x   1 root root      831 07-21 03:33 libevent.la
lrwxrwxrwx   1 root root       21 07-21 03:33 libevent.so -> libevent-1.4.so.2.1.3


安装OK。

3. 安装memcached,同时需要安装中指定libevent的安装位置
[root@localhost software]# tar zxvf memcached-1.4.0.tar.gz
[root@localhost memcached-1.4.0]# ./configure –with-libevent=/usr
[root@localhost memcached-1.4.0]# make
[root@localhost memcached-1.4.0]# make intall

4. 测试是否成功安装memcached
[root@localhost memcached-1.4.0]# ls -al /usr/local/bin | grep memcached
-rwxr-xr-x  1 root root  188225 07-21 03:35 memcached

安装OK。

三. 如何启动 memcached 服务:
只需要启动一个 memcached 监护进程,监护进程不需要配置文件,只要在命令行里面加三四个参数就可以了:
[root@localhost bin]# memcached -d -m 100 -u root -l 127.0.0.1 -p 11211 -c 256 -P /tmp/memcached.pid
-d: (run as a daemon) 选项是启动一个守护进程
-m:(max memory to use for items in megabytes (default: 64 MB))是分配给Memcache使用的内存数量,单位是MB,我这里是100MB,
-u:(assume identity of <username> (only when run as root))是运行Memcache的用户,我这里是root,
-l:(interface to listen on)是监听的服务器IP地址,如果有多个地址的话,这里指定了服务器的IP地址127.0.0.1,
-p:是设置Memcache监听的端口,这里设置了11211,最好是1024以上的端口,
-c:选项是最大运行的并发连接数,默认是1024,这里设置了256,根据服务器的负载量来设定,
-P:(save PID in <file>, only used with -d option)是设置保存Memcache的pid文件,这里是保存在 /tmp/memcached.pid


注:也可以启动多个守护进程,不过端口不能重复。

四. 安装 Memcached 的PHP扩展:
在PHP中使用Memcached,有两种方式:
一种是安装PHP的memcached扩展。该扩展是用c写的,效率较高,需要在服务器上安装。
另外一种则是直接使用客户端的php-memcached-client类库。
下面是使用PECL中Memcache的专用扩展,因为毕竟是用C写的,效率高,而且安装部署起来也比较方便。
1. 在 http://pecl.php.net/package/memcache 选择相应想要下载的memcache版本。我下载的是:memcache-2.2.5.tgz 版本。
2. 安装 memcache
[root@localhost software]# tar zxvf memcache-2.2.5.tgz
[root@localhost software]# cd memcache-2.2.5
[root@localhost memcache-2.2.5]# /usr/bin/phpize
[root@localhost memcache-2.2.5]# ./configure –enable-memcache –with-php-config=/usr/bin/php-config –with-zlib-dir
[root@localhost memcache-2.2.5]# make
[root@localhost memcache-2.2.5]# make install
这步会有类似这样的提示:Installing shared extensions: /usr/local/php/modules
3. 把/etc/php.ini中的extension_dir = “./”修改为:extension_dir = "/usr/lib/php/modules"
4. 并添加: extension=memcache.so

也可执行以下shell命令,对php.ini文件的修改:
sed -i 's#extension_dir = "./"#extension_dir = "/usr/local/webserver/php/lib/php/extensions/no-debug-non-zts-20060613/"/nextension = "memcache.so"/n#' /usr/local/webserver/php/etc/php.ini


五. 安装C/C++ Memcached客户端库:libmemcached
下载:http://download.tangent.org/libmemcached-0.32.tar.gz
1. 安装 libmemcached
[root@localhost src]# tar zxvf libmemcached-0.32.tar.gz
[root@localhost src]# cd libmemcached-0.32
[root@localhost libmemcached-0.32]# ./configure --prefix=/usr
[root@localhost libmemcached-0.32]# make && make install
2. 检查安装结果
[root@localhost src]# ls /usr/lib/libmemcache* //库文件
[root@localhost src]# ls /usr/include/libmemcached/* //头文件
[root@localhost src]# ls /usr/bin/mem* //命令行工具

六. 应用:
1. 启动 memcache 服务
[root@localhost bin]# memcached -d -m 100 -u root -l 127.0.0.1 -p 11211 -c 256 -P /tmp/memcached.pid
2. 重启 Web 服务器
[root@localhost bin]# service httpd restart
3. 创建 demo 测试程序
<?php
//连接
$mem = new Memcache;
$mem->connect("127.0.0.1", 11211);

echo 'Memcache Version is:'.$mem->getVersion().'<br/>';

//保存数据
$mem->set('key1', 'This is first memcache demo', 0, 60);
$val = $mem->get('key1');
echo "Get key1 value: ".$val."<br/>"

//关闭连接
$mem->close();
?>


4. Memcached客户端与tokyotyrant DB操作访问
<?php
$memcache = new memcache();
$memcache->addServer('127.0.0.1:1978');

function microtime_float()
{
    list($usec, $sec) = explode(" ", microtime());
    return ((float)$usec + (float)$sec);
}
$time_start = microtime_float();

$data = 'abc123';
for($i = 0;$i <= 20000 ;$i++){
   $key = (string) rand(1,100);
   $memcache->set($key, $data);
}

for($i = 0;$i <= 20000 ;$i++){
   $key = (string) rand(1,100);
   echo $data = $memcache->get($key).'-'.$i.'<br/>';
}

$time_end = microtime_float();
$time = $time_end - $time_start;
echo $time;

$memcache->close();
?>

5. C/C++ 与 Memcached 结合代码
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <libmemcached/memcached.h>

int main(int argc, char *argv[])
{
    memcached_st *memc;
    memcached_return rc;
    memcached_server_st *servers;
    char value[8191];

    //连接服务器
    memc = memcached_create(NULL);
    servers = memcached_server_list_append(NULL, "127.0.0.1",11211, &rc);
    rc = memcached_server_push(memc, servers);
    memcached_server_free(servers);

    //存储数据
    strcpy(value, "This is c first value");
    rc = memcached_set(memc, "key1", 4, value, strlen(value),
    (time_t)180, (uint32_t)0);
    if (rc == MEMCACHED_SUCCESS) {
    printf("Save key:key1 data:/"%s/" success./n", value);
    }

    //获取数据
    char return_key[MEMCACHED_MAX_KEY];
    size_t return_key_length;
    char *return_value;
    size_t return_value_length;
    char *keys[]= {"key1"};
    size_t key_length[]= {4};
    uint32_t flags;
    rc = memcached_mget(memc, keys, key_length, 1);
    return_value = memcached_fetch(memc, return_key,
    &return_key_length, &return_value_length, &flags, &rc);
    if (rc == MEMCACHED_SUCCESS) {
    printf("Fetch key:%s data:%s/n", return_key, return_value);
    }

    //删除数据
    rc = memcached_delete(memc, "key1", 4, (time_t)0);
    if (rc == MEMCACHED_SUCCESS) {
    printf("Delete Key key1 success./n");
    }
   
    //释放内存
    memcached_free(memc);
    return 0;
}

编译源代码:
[root@localhost html]# gcc -o cmem cmem.c -lmemcached
[root@localhost html]# ./cmem //执行
Save key:key1 data:"This is c first value" success.
Fetch key:key1 data:This is c first value
Delete Key key1 success.


6. C/C++ 与 Memcached 分布式结合代码
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <libmemcached/memcached.h>

int main(int argc, char *argv[])
{
    memcached_st *memc;
    memcached_return rc;
    memcached_server_st *servers;
    char value[8191];

    //connect multi server
    memc = memcached_create(NULL);
    servers = memcached_server_list_append(NULL, "localhost", 11211, &rc);
    servers = memcached_server_list_append(servers, "localhost", 11212, &rc);
    rc = memcached_server_push(memc, servers);
    memcached_server_free(servers);

    //Save multi data
    size_t i;
    char *keys[]= {"key1", "key2", "key3"};
    size_t key_length[]= {4, 4, 4};
    char *values[] = {"This is c first value", "This is c second value", "This is c third value"};
    size_t val_length[]= {21, 22, 21};
    for (i=0; i <3; i++) {
    rc = memcached_set(memc, keys[i], key_length[i], values[i], val_length[i], (time_t)180,(uint32_t)0);
    if (rc == MEMCACHED_SUCCESS) {
        printf("Save key:%s data:/"%s/" success./n", keys[i], values[i]);
    }
    }

    //Fetch multi data
    char return_key[MEMCACHED_MAX_KEY];
    size_t return_key_length;
    char *return_value;
    size_t return_value_length;
    uint32_t flags;
    rc = memcached_mget(memc, keys, key_length, 3);
    while ((return_value = memcached_fetch(memc, return_key, &return_key_length, &return_value_length, &flags, &rc))) {
    if (rc == MEMCACHED_SUCCESS) {
        printf("Fetch key:%s data:%s/n", return_key, return_value);
    }
    }
   
    //Delete multi data
    for (i=0; i <3; i++) {
    rc = memcached_set(memc, keys[i], key_length[i], values[i], val_length[i], (time_t)180, (uint32_t)0);
    rc = memcached_delete(memc, keys[i], key_length[i], (time_t)0);
    if (rc == MEMCACHED_SUCCESS) {
        printf("Delete %s success/n", keys[i], values[i]);
    }
    }
    //free
    memcached_free(memc);
    return 0;
}

编译源代码:
[root@localhost html]# gcc -o cmultmem cmultmem.c -lmemcached
[root@localhost html]# ./cmultmem //执行
Save key:key1 data:"This is c first value" success.
Save key:key2 data:"This is c second value" success.
Save key:key3 data:"This is c third value" success.
Fetch key:key2 data:This is c second value
Fetch key:key3 data:This is c third value
Fetch key:key1 data:This is c first value
Delete key1 success
Delete key2 success
Delete key3 success

以上c/c++代码摘自:黑夜路人

7. 查看Memcache进程
[root@localhost html]# ps aux | grep memcached
root     11382  0.0  0.7  55124  1896 ?        Ssl  13:06   0:00 memcached -d -m 100 -u root -l 127.0.0.1 -p 11211 -c 256 -P /tmp/memcached.pid
root     11395  0.0  0.2   3912   664 pts/1    R+   13:08   0:00 grep memcached


8. 结束Memcache进程
[root@localhost html]# kill `cat /tmp/memcached.pid`


For more:http://cn.php.net/memcache

相关文章:

被算法“监控”的打工人,这家公司 150 人被算法裁定为“不敬业”

整理 | 禾木木 出品 | AI科技大本营&#xff08;ID:rgznai100&#xff09; 近日&#xff0c;一家公司通过 AI 算法裁掉三成员工的消息在网上引起热议。当你上班时突然收到一封邮件显示“效率低下”而要求马上离开公司&#xff0c;你会怎么想呢&#xff1f; 据 Game World Obser…

(转)I 帧和 IDR 帧的区别

I 帧和 IDR 帧的区别&#xff1a;http://blog.csdn.net/skygray/article/details/6223358 IDR 帧属于 I 帧。解码器收到 IDR frame 时&#xff0c;将所有的参考帧队列丢弃 &#xff08;用x264_reference_reset 函数实现——在 encoder.c 文件中&#xff09; 。这点是所有 I 帧…

ExtJs 备忘录(3)—— Form表单(三) [ 数据验证 ]

正文一、资料 1.1. 表单提示的方式设置&#xff0c;如&#xff1a; Ext.form.Field.prototype.msgTargetside 该设置为枚举值&#xff1a;qtip,side,title,under qtip&#xff1a;把鼠标移动到控件就可以显示提示信息了&#xff0c;有点像设置了title的input标签一样的效果…

Dynamo 以及一致性哈希简介

本介绍参考 Amazon 的 Dynamo 论文。需要更详细更准确信息的同学请直接阅读原文。 (原文地址http://s3.amazonaws.com/AllThingsDistributed/sosp/amazon-dynamo-sosp2007.pdf) 这篇论文本身没提出什么新的思想&#xff0c;正如论文中所说&#xff0c;贡献在于把非常多的技术结…

如何更快速加载你的JS页面

确保代码尽量简洁 不要什么都依赖JavaScript。不要编写重复性的脚本。要把JavaScript当作糖果工具&#xff0c;只是起到美化作用。别给你的网站添加大量的JavaScript代码。只有必要的时候用一下。只有确实能改善用户体验的时候用一下。 尽量减少DOM访问 使用JavaScript访问DOM元…

性价比超高:苹果发布了新数据集,助力室内场景理解

作者&#xff1a;刘媛媛 来源&#xff1a;数据实战派前言计算机视觉界一直渴望能够找到一种方法&#xff0c;让计算机和人们都能够理解室内场景的复杂性。对于许多基本的场景理解任务&#xff0c;很难或不可能从真实图像中获得每像素地面实况标签。一部分研究人员选择通过使用交…

42. fastjson处理下划线和驼峰问题的方法和源码分析

一. 前言 在开发过程中经常遇到json解析和生成的问题&#xff0c;所以用自己也一直用fastjson来实现这个功能。 但是&#xff0c;最近遇到一个问题: json字符串里面的数据很多都是"_"下划线的比如&#xff0c;op_id。 而在java里面&#xff0c;很多都是驼峰的写法&…

Cacti Weathermap添加主机在线状态图示检测

Weathermap 中文名称翻译为 气象图weathermap版本支持&#xff1a;0.94及最新版1、首先添加气象图 图例像这样。编辑需要添加图例的气象图配置文件 (气象图配置文件默认在/var/www/html/plugins/weathermap/configs/ 目录中)其中 KEYPOS指定全局图例名称以及 图例位置和 图例标…

jquery技巧总结

一、简介1.1、概述随着WEB2.0及ajax思想在互联网上的快速发展传播&#xff0c;陆续出现了一些优秀的Js框架&#xff0c;其中比较著名的有Prototype、YUI、jQuery、mootools、Bindows以及国内的JSVM框架等&#xff0c;通过将这些JS框架应用到我们的项目中能够使程序员从设计和书…

Unet网络实现叶子病虫害图像分割

作者|李秋键 出品|AI科技大本营(ID:rgznai100) 智能化农业作为人工智能应用的重要领域&#xff0c;对较高的图像处理能力要求较高&#xff0c;其中图像分割作为图像处理方法在其中起着重要作用。图像分割是图像分析的关键步骤, 在复杂的自然背景下进行图像分割, 难度较大。 在传…

SilverLight 4页面跳转大全

http://blog.csdn.net/lihaiyin/article/details/5674766 //Silverlight页面的跳转 //(Application.Current.RootVisual as IContent).Content new DragControl(); //普通页面跳转 HtmlWindow html HtmlPage.Window; //html.Navigate(new Uri("http://www.0379zd.co…

Linux 性能监控常用命令

工具简单介绍top查看进程活动状态以及一些系统状况vmstat查看系统状态、硬件和系统信息等iostat查看CPU 负载&#xff0c;硬盘状况sar综合工具&#xff0c;查看系统状况mpstat查看多处理器状况netstat查看网络状况iptraf实时网络状况监测tcpdump抓取网络数据包&#xff0c;详细…

jquery 1.6以上版本 全选

2019独角兽企业重金招聘Python工程师标准>>> <html xmlns"http://www.w3.org/1999/xhtml"> <head><title>全选&#xff0c;不全选&#xff0c;反选</title><script src"jquery.js" type"text/javascript"…

想提高代码水平,做到这点就够了

【CSDN 编者按】本篇文章来自于《程序员》杂志的一位老读者&#xff0c;他从大学时最深刻的记忆谈起&#xff0c;到编程路上的心得体会&#xff0c;再到对广大年轻程序员的建议&#xff0c;全篇娓娓道来&#xff0c;希望能对大家有所帮助。作者 | 姜宁 华为开源能力中心技术专…

modified: xxx(modified content, untracked content)

from:://http://blog.csdn.net/huguohu2006/article/details/7045052 提交代码到服务器后发现git clone下来的有些目录是空的。 查看服务器的目录果然是空的。看本季git add . 后查看git status modified: xxx(modified content, untracked content) 大概意思是xxx目录没有…

一些JSON相关的函数

JSON作为一种轻量的数据传输格式&#xff0c;越来越受到人们的青睐。下面是我仿照Prototype的一些实现。 JSONFilter:/^///*-secure-([/s/S]*)/*///s*$/, unfilterJSON:function(json,filter) { return json.replace((filter || dom.JSONFilter), function(a,b){ return b |…

太任性!17 岁少年买不到回国机票,因“泄愤”攻击航司系统,被判刑 4 年

整理 | 王晓曼出品 | 程序人生&#xff08;ID&#xff1a;coder _life&#xff09;因买不到回国机票&#xff0c;一气之下&#xff0c;身处境外的17岁少年陈某竟多次、持续攻击某航空公司计算机系统&#xff0c;致使该航空公司对外服务网络全面瘫痪近四小时&#xff0c;5000余万…

hbase2.0.0-安装部署

依赖hadoop 环境&#xff0c;我这边的版本是hadoop-2.6.5 选择hbase2.0.0版本的时候&#xff0c;去官网查看支持的hadoop版本 1、伪分布式安装 下载&#xff1a;http://mirror.bit.edu.cn/apache/hbase/2.0.0-alpha4/ 版本&#xff1a;hbase-2.0.0-alpha4-bin.tar.gz 2、tar -z…

Git详解之二 Git基础

Git 基础 读完本章你就能上手使用 Git 了。本章将介绍几个最基本的&#xff0c;也是最常用的 Git 命令&#xff0c;以后绝大多数时间里用到的也就是这几个命令。读完本章&#xff0c;你就能初始化一个新的代码仓库&#xff0c;做一些适当配置&#xff1b;开始或停止跟踪某些文件…

一致性哈希(Consistent Hashing)

在大型web应用中&#xff0c;缓存可算是当今的一个标准开发配置了。在大规模的缓存应用中&#xff0c;应运而生了分布式缓存系统。分布式缓存系统的基本原理&#xff0c;大家也有所耳闻。key-value如何均匀的分散到集群中&#xff1f;说到此&#xff0c;最常规的方式莫过于hash…

CT片居然可以这么玩:用头部CT断层扫描片复原三维头像

作者&#xff1a;天元浪子 来源&#xff1a;Python作业辅导员前言CT是现代医学影像的主力设备&#xff0c;寻常百姓并不陌生。通常&#xff0c;一张CT片由多张连续断层扫描的图像组成。在医生眼中&#xff0c;CT片展示了人体器官的形态和性质&#xff0c;是判断病人健康状况的重…

Nginx学习笔记(一) Nginx架构

Nginx全程是什么&#xff1f; Nginx ("engine x") 是一个高性能的 HTTP 和 反向代理 服务器&#xff0c;也是一个 IMAP/POP3/SMTP 代理服务器。 daemon守护线程 nginx在启动后&#xff0c;在unix系统中会以daemon的方式在后台运行&#xff0c;后台进程包含一个master…

PXE实现批量部署linux系统

pxe批量部署linux服务器1、pxe介绍PXE是有intel设计的协议&#xff0c;它可以使计算机通过网络启动&#xff0c;协议分为client和server两端&#xff0c;PXEclient在网卡的ROM中&#xff0c;当计算机引导时&#xff0c;BIOS把PXE client调入内存中执行&#xff0c;并显示出命令…

首场见习挑战赛倒计时3天!20000元奖学金瓜分就等你了!

CSDN软件开发精英赛是基于“C认证—软件工程师能力认证考试”而设立的编程比赛&#xff0c;大赛联合广大科技企业设置丰厚礼品及30万元奖学金。从7月22日官宣到今日&#xff0c;短短一个月内&#xff0c;大赛已经吸引了来自全国的2000&#xff0b;开发者参与其中。第一轮“见习…

一致性哈希算法以及其PHP实现

在做服务器负载均衡时候可供选择的负载均衡的算法有很多&#xff0c;包括&#xff1a; 轮循算法&#xff08;Round Robin&#xff09;、哈希算法&#xff08;HASH&#xff09;、最少连接算法&#xff08;Least Connection&#xff09;、响应速度算法&#xff08;Response Time…

Linux入门(四)

目录&#xff1a; 1234567891011121314一、根文件系统层级标准FHS二、bash的基础特性&#xff08;一&#xff09;1.命令历史 2.命令行补全 3.路径补全 4.命令行展开 5.命令执行的状态结果 6.引用 7.快捷键 三、目录管理相关命令mkdir、rmdir、tree四、引用命令的执行结果五、文…

OSI[七层]与TCP/IP[四层]模型简述简图

OSI参考模型&#xff08;OSI/RM&#xff09;的全称是开放系统互连参考模型&#xff08;Open System Interconnection Reference Model&#xff0c;OSI/RM&#xff09;&#xff0c;它是由国际标准化组织&#xff08;International Standard Organization&#xff0c;ISO&#xf…

中国国际消费电子博览会拥抱转型,全新面貌拭目以待!

2021年9月24—26日&#xff0c;第十九届中国国际消费电子博览会&#xff08;简称电博会&#xff09;将在青岛国际会展中心隆重举行&#xff0c;如今距离电博会开幕已不到3个月的时间&#xff0c;全国各地的参展企业跃跃欲试、积极筹备。 长久以来&#xff0c;电博会为全球消费…

Fragment提交transaction导致state loss异常

下面自从Honeycomb发布后&#xff0c;下面栈跟踪信息和异常信息已经困扰了StackOverFlow很久了。 java.lang.IllegalStateException: Can not perform this action after onSaveInstanceState at android.support.v4.app.FragmentManagerImpl.checkStateLoss(FragmentManager.j…

ASP网络编程从入门到精通 下载

《ASP网络编程从入门到精通》 清华大学出版社 特点&#xff1a; 面向ASP零基础读者&#xff0c;循序渐进 全面分析ASP技术细节 用代码描述个个知识点&#xff0c;操作性强 通过典型模块设计&#xff0c;体会ASP的奥妙 通过网上商城购物系统&#xff0c;增加项目开发经验 适合的…