CenterOS安装coreseek ubuntu 安装coreseek

[如何正确安装libsphinxclient](https://blog.csdn.net/weixin_42233723/article/details/80531622)(https://blog.csdn.net/xueling022/article/details/52881228)

安装时phpize和php-conf最好精确到目录

技术文档

http://note.youdao.com/noteshare?id=ecdfb9bce103133a2d0b2c580141c47c&sub=8150DC20DD9B44F89BA567E2A8091CE4

点击跳转

[如何使用:https://blog.csdn.net/nuli888/article/details/51892776#]

[ubuntu 安装教程]https://www.jianshu.com/p/3f7466d6b395

1. 安装准备(CenterOS6.5 64位版本)

如果已安装,请注意软件的版本冲突。

yum install -y make gcc g++ gcc-c++ libtool autoconf automake imake libxml2-devel expat-devel mysql-devel

2. 安装mmseg3

# wget http://www.phpercode.com/wp-content/uploads/2016/12/coreseek-4.1-beta.tar-3.gz

# tar zxvf coreseek-4.1-beta.tar-3.gz

# cd coreseek-4.1-beta/mmseg-3.2.14

# ./bootstrap    #bootstrap 命令用来检测安装环境并且自动修复

# ./configure --prefix=/usr/local/mmseg3 #指定安装目录

# make && make install #编译和安装

3. 安装Coreseek

# cd ../csft-4.1

# sh buildconf.sh     #输出的warning信息可以忽略,如果出现error则需要解决

# ./configure --prefix=/usr/local/coreseek  --without-unixodbc --with-mmseg --with-mmseg-includes=/usr/local/mmseg3/include/mmseg/ --with-mmseg-libs=/usr/local/mmseg3/lib/ --with-mysql

# make && make install

编译和安装的时候如果报以下错,请按照官网方法解决。 /usr/local/sphinx/src/sphinx.cpp:15557:undefined reference to `libiconv_open’

 libsphinx.a(sphinx.o)(.text+0x53a01):/usr/local/sphinx/src/sphinx.cpp:15575:undefined

 reference to `libiconv’

 libsphinx.a(sphinx.o)(.text+0x53a28):/usr/local/sphinx/src/sphinx.cpp:15581:undefined

 reference to `libiconv_close’

 collect2: ld returned 1 exit status

 make[2]: * [indexer] Error 1

 make[2]: Leaving directory `/usr/local/sphinx/src’

 make[1]: * [all] Error 2

 make[1]: Leaving directory `/usr/local/sphinx/src’

 make: * [all-recursive] Error 1

官网解决办法:

In the meantime I’ve change theconfiguration file and set

#define USE_LIBICONV 0 in line 8179.

修改/csft-4.1/configure 文件把 #define USE_LIBICONV 0 最后的数值由1改为0

重新编译。

4. 测试mmseg分词,coreseek搜索

测试前,需要预先设置好字符集为zh_CN.UTF-8,确保正确显示中文

# cd ../testpack

# cat var/test/test.xml #查看xml文件

# /usr/local/mmseg3/bin/mmseg -d /usr/local/mmseg3/etc var/test/test.xml #使用mmseg 对xml文件进行分词

# /usr/local/coreseek/bin/indexer -c etc/csft.conf --all

# /usr/local/coreseek/bin/search -c etc/csft.conf 网络搜索

5. Sphinx扩展安装

安装依赖libsphinxclient

# cd /root/coreseek-4.1-beta/csft-4.1/api/libsphinxclient

# ./configure  --prefix=/usr/local/sphinxclient 报错状态 configure: creating ./config.status  

config.status: creating Makefile  

config.status: error: cannot find input file: Makefile.in   #报错configure失败 处理configure报错编译过程中报了一个config.status: error: cannot find input file: src/Makefile.in这个的错误,然后运行下列指令再次编译就能通过了:

# aclocal  

# libtoolize --force  

# automake --add-missing  

# autoconf  

# autoheader  

# make clean    

# ./configure  

# make && make install

安装sphinx的PHP扩展

http://pecl.php.net/package/sphinx

## wget http://pecl.php.net/get/sphinx-1.3.0.tgz

# wget http://pecl.php.net/get/sphinx-1.3.3.tgz

# tar -zxvf sphinx-1.3.3.tgz

# cd sphinx-1.3.3

# phpize

# ./configure --with-php-config=/usr/bin/php-config --with-sphinx

# make && make install

如果安装成功,会出现类似

“Installing shared extensions:/usr/local/php/lib/php/extensions/no-debug-non-zts-20090626/”,表示成功。

进入该目录下会发现生成了一个sphinx.so 文件

在php.ini 中加载该 so 文件

extension=/usr/local/php/lib/php/extensions/no-debug-non-zts-20100525/sphinx.so

重启apache,如果使用phpinfo()打印服务可以看到sphinx服务。

6. 创建sphinx统计表

CREATE TABLE sph_counter(

    counter_id INTEGER PRIMARY KEY NOT NULL,

    max_doc_id INTEGER NOT NULL

 );

7. 创建配置sphinx与mysql的配置文件

vi /usr/local/coreseek/etc/csft_mysql.conf    点击查看

8. 命令列表

命令必须在路径下执行命令或加上绝对路径coreseek/bin

indexer: 用于创建全文索引

执行索引(查询、测试前必须执行一次)

# indexer --config /usr/local/coreseek/etc/csft_mysql.conf --all --rotate

执行增量索引

# indexer --config /usr/local/coreseek/etc/csft_mysql.conf delta --rotate

合并索引(为了防止多个关键字指向同一个文档加上--merge-dst-range deleted 0 0)

# indexer --config /usr/local/coreseek/etc/csft_mysql.conf --merge main delta --rotate --merge-dst-range deleted 0 0

indexer

indexer是Sphinx的两个关键工具之一。不管是从命令行直接调用,还是作为一个较大的脚本的一部分使用,indexer都只负责一件事情——收集要被检索的数据

indexer的调用语法基本上是这样:

indexer [OPTIONS] [indexname1 [indexname2 [...]]]

用户可以在sphinx.conf中设置好可能有哪些索引(index)(这些索引可以在晚些时候再搜索),因此在调用indexer的时候,最简单的情况下,只需要告诉它你要建立哪个(或者哪些)索引就行了。

假设sphinx.conf 包含了两个索引的具体设置, mybigindex 和 mysmallindex, ,你可以这么调用:

# 使用默认配置执行一个索引,默认文件为/coreseek/etc/csft.conf

$ indexer mybigindex

# 使用默认配置执行二个索引,默认文件为/coreseek/etc/csft.conf

$ indexer mysmallindex mybigindex

# 使用绝对路径、指定配置文件来执行索引

$ /usr/local/coreseek/bin/indexer -c /usr/local/coreseek/etc/csft_mysql.conf index1

在配置文件sphinx.conf里面,用户可以为他们的数据指定一个或多个索引。然后调用indexer来对其中一个特定的索引进行重新编制索引操作,或者是重新编制所有索引——all不限于某一个或同时全部,用户总是可以指定现有索引的一个组合。

indexer的大部分选项都可以在配置文件中给出,然而有一部分选项还需要在命令行上指定,这些选项影响编制索引这一操作是如何进行的。这些选项列举如下:

[if !supportLists]· [endif]--config  (简写为-c ) 使 indexer 将指定的文件file作为配置文件。 通常,indexer是会在安装目录(例如e.g. /usr/local/sphinx/etc/sphinx.conf ,如果sphinx被安装在/usr/local/sphinx)中寻找sphinx.conf,若找不到,则继续在用户在shell中调用indexer时所在的目录中寻找。 这个选项一般在共享sphinx安装的情况下使用,比如二进制文件安装在/usr/local/sphinx,而不同用户都有权定制自己的sphinx设置。或者在同一个服务器上运行多个实例的情况下使用。在上述两中情况中,用户可以创建自己的sphinx.conf文件,然后把它做为参数传给indexer。例如:

$ ./indexer --config /home/myuser/sphinx.conf myindex

[if !supportLists]· [endif]

[if !supportLists]· [endif]--all 使indexer对sphinx.conf文件中列出的所有索引进行重新编制索引,这样就不比一次列出每个索引的名字了。这个选项在配置文件较小的情况下,或者在类似基于cron的维护工作中很有用。在上述情况中,整个索引集每天或每周或别的什么合适的时间间隔中就重新建立一次。用法示例:

$ ./indexer --config /home/myuser/sphinx.conf --all

[if !supportLists]· [endif]

[if !supportLists]· [endif]--rotate 用于轮换索引。对新的文档建立索引时几乎肯定都确保搜索服务仍然可用,除非你有信心在搜索服务停止同时不给你的用户带来困扰。--rotate建立一个额外的索引,并列于原有索引(与原有索引在相同目录,简单地在原有索引文件名基础上加一个.new后缀)。一旦这个额外的索引建立完成,indexer给searchd发一个SIGHUP信号做为通知。searchd会尝试将索引重新命名(给原有索引加上.old后缀,而把带有.new后缀的新索引改为原名,以达替换之目的),继而用新的文件重启服务。依 seamless_rotate 选项设定之不同,在新索引可用之前可能有一点小的延迟。用法示例:

$ ./indexer --config /usr/local/coreseek/etc/mysql.conf --rotate --all

[if !supportLists]· [endif]

[if !supportLists]· [endif]--quiet 使indexer不输出除错误(error)外的任何东西。这个选项通常用在cron定时任务的情境下或者脚本中,这些情况下大部分输出是无关紧要或完全没用的,除非是发生了某些种类的错误。用法示例:

$ ./indexer --config /usr/local/coreseek/etc/mysql.conf --rotate --all --quiet

[if !supportLists]· [endif]

[if !supportLists]· [endif]--noprogress 不随时显示进度信息,而是仅在索引结束时报告最终的状态细节(例如为哪些文档建立了索引,建立索引的速度等)。当脚本没有运行在一个控制台(console,或“tty”)时,这个选项是默认的。用法示例:

$ ./indexer --config /usr/local/coreseek/etc/mysql.conf --rotate --all --noprogress

[if !supportLists]· [endif]

[if !supportLists]· [endif]--buildstops  像建立索引一样扫描索引对应的数据源,产生一个最终会被加入索引的词项的列表。换种说法,产生一个用这个索引可以检索的词项的列表。注意,这个选项使indexer并不真正更新指定的索引,而只是“假装”建在立索引似地处理一遍数据,包括运行sql_query_pre或者sql_query_post选项指定的查询。outputfile.txt文件最终会包含一个词表,每行一个词,按词频排序,高频在前。参数N指定了列表中最多可出现的词项数目,如果N比索引中全部词项的数目还大,则返回的词项数就是全部词项数。客户端应用程序利用这种字典式的词表来提供“您是要搜索。。。吗?(Did you mean…)”的功能,通常这个选项与下面要讲的--buildfreqs选项一同使用。示例:

$ indexer myindex --buildstops word_freq.txt 1000

[if !supportLists]· [endif]

这条命令在当前目录产生一个word_freq.txt文件,内含myindex这个索引中最常用的1000个词,且最常用的排在最前面。注意,当指定了多个索引名或使用了--all选项(相当于列出配置文件中的所有索引名)时,这个选项对其中的最后一个索引起作用。

[if !supportLists]· [endif]

[if !supportLists]· [endif]--buildfreqs 与 --buildstops一同使用 (如果没有指定 --buildstops 则--buildfreqs也被忽略). 它给--buildstops产生的词表的每项增加一个计数信息,即该词在索引中共出现了多少次,这在建立停用词(stop words,出现特别普遍的词)表时可能有用。在开发“您是要搜索。。。吗?(Did you mean…)”的功能时这个选项也能帮上忙,因为有了它你就能知道一个词比另一个相近的词出现得更频繁的程度。示例:

$ indexer myindex --buildstops word_freq.txt 1000 --buildfreqs

[if !supportLists]· [endif]

这个命令将产生一个类似于上一条命令的word_freq.txt ,但不同在于,每个词的后面都会附加一个数字,指明在指定的索引中这个词出现了多少次。

[if !supportLists]· [endif]

[if !supportLists]· [endif]--merge  用于在物理上将多个索引合并,比方说你在使用“主索引+增量索引”模式,主索引很少改变,但增量索引很频繁地重建,而--merge选项允许将这两个索引合而为一。操作是从右向左进行的,即先考察src-index的内容,然后在物理上将之与dst-index合并,最后结果留在dst-index里。用伪代码说就是dst-index += src-index。示例:

$ indexer --merge main delta --rotate

[if !supportLists]· [endif]

上例中main是主索引,很少更动,delta是增量索引,频繁更新。上述命令调用indexer将delta的内容合并到main里面并且对索引进行轮换。

[if !supportLists]· [endif]

[if !supportLists]· [endif]--merge-dst-range  在合并索引的时候运行范围过滤。具体地说,向目标索引 (是 --merge 的一个参数,如果没有指定 --merge, 则--merge-dst-range 也被忽略)合并时,indexer会对将要合并进去的文档做一次过滤,只有通过过滤才能最终出现在目标索引中。举一个实用的例子,假设某个索引有一个“已删除(deleted)”属性,0代表“尚未删除”。这样一个索引可以用如下命令进行合并:

$ indexer --merge main delta --merge-dst-range deleted 0 0

[if !supportLists]· [endif]

$ /usr/local/coreseek/bin/indexer -c /usr/local/coreseek/etc/csft_mysql.conf

[if !supportLists]· [endif]

--merge main delta --rotate --merge-dst-range deleted 0 0

[if !supportLists]· [endif]

这样标记为已删除的文档(值为1)就不会出现在新生成的目标索引中了。这个选项可以在命令行上指定多次,以便指定多个相继的过滤,这样一个文档要想合并到最终的目标索引中去,就必须依次通过全部这些过滤。

[if !supportLists]· [endif]

[if !supportLists]· [endif]--dump-rows  用于从SQL数据源导出获取的数据到指定的文件,每行数据使用MySQL兼容的格式。导出的数据用于完整的再现indexer收到的数据并帮助重现索引时的问题。

[if !supportLists]· [endif]--verbose 确保每条导致索引出现问题的行都会报告出来 ( 重复, 为零, 或者没有文档编号ID; 或者外部文件字段的Io问题; 等等) . 默认情况下,该选项是关闭的,作为替代的是报告问题摘要。

[if !supportLists]· [endif]--sighup-each 有助于重建多个较大的索引并在每个索引轮换完成后马上生效可被searchd使用. 使用 --sighup-each, indexer 会在每个索引成功完成各项工作后给searchd发送SIGHUP信号。 (默认做法是在全部索引建立后发送SIGHUP信号)

searchd

searchd 是一个守护进程,其他软件(例如WEB程序)可以通过这个守护进程进行全文检索

-h,--help         列出可以在你当前的searchd构建上调用的参数。-c,--config              从指定的文件读取配置(默认文件为csft.conf)。

$ searchd -c /usr/local/coreseek/etc/csft_mysql.conf      #启动服务

--stop                                用于异步停掉 searchd,使用sphinx.conf中所指定的PID文件,因此您可能还需要用--config选项来确认searchd使用哪个配置文件。值得注意的是,调用 --stop 会确保用 UpdateAttributes() 对索引进行的更动会反应到实际的索引文件中去,示例:

$ ./searchd --config /usr/local/coreseek/etc/mysql.conf --stop

--stopwait                       用于同步停止 searchd. --stop 本质上是通知运行实例退出 (通过发送 SIGTERM信号) 然后立刻返回. --stopwait 将会一直等待直到 searchd 实例确实的完成了关闭(例如,保存所有在内存中的属性改变) 并退出, 示例:

$ ./searchd --config /usr/local/coreseek/etc/mysql.conf --stopwait

可能的退出代码如下:

[if !supportLists]· [endif]0 表示成功;

[if !supportLists]· [endif]1 表示连接到运行的searchd守护进程失败;

[if !supportLists]· [endif]2 表示守护进程在关闭时报告了错误;

[if !supportLists]· [endif]3 表示守护进程关闭时崩溃。

--status                            用来查询运行中的searchd实例的状态,,使用指定的(也可以不指定,使用默认)配置文件中描述的连接参数。它通过配置好的第一个UNIX套接字或TCP端口与运行中的实例连接。一旦连接成功,它就查询一系列状态和性能计数器的值并把这些数据打印出来。在应用程序中,可以用status()API调用来访问相同的这些计数器。示例:

$ searchd --status

$ searchd --config /home/myuser/sphinx.conf --status

$cl->Status ();     # api调用方式

--iostats                         当使用日志时(必须在sphinx.conf中启用query_log选项)启用--iostats会对每条查询输出关于查询过程中发生的输入输出操作的详细信息,会带来轻微的性能代价,并且显然会导致更大的日志文件。更多细节请参考 query log format 一节。可以这样启动searchd:

$ searchd --config /home/myuser/sphinx.conf --iostats

--cpustats                       使实际CPU时间报告(不光是实际度量时间(wall time))出现在查询日志文件(每条查询输出一次)和状态报告(累加之后)中。这个选项依赖clock_gettime()系统调用,因此可能在某些系统上不可用。可以这样启动searchd:

$ searchd --config /home/myuser/sphinx.conf --cpustats

--port portnumber     (可简写为-p) 指定searchd监听的端口,通常用于调试。这个选项的默认值是9312,但有时用户需要它运行在其他端口上。在这个命令行选项中指定端口比配置文件中做的任何设置优先级都高。有效的端口范围是0到65535,但要使用低于1024的端口号可能需要权限较高的账户。使用示例:

$ searchd  --config /home/myuser/sphinx.conf  --port 9313 #监听地址,端口或路径,会覆盖配置设置

--index        (或者缩写为 -i ) 强制searchd只提供针对指定索引的搜索服务。跟上面的--port相同,这主要是用于调试,如果是长期使用,则应该写在配置文件中。使用示例:

$ searchd --config /home/myuser/sphinx.conf --index myindex

--logdebug                          让额外的调试信息输出到守护进程日志中。使用的较少,用于帮助调试难以重现的请求。

sphinxapi: 一系列searchd 的客户端API 库,用于流行的Web脚本开发语言(PHP, Python, Perl, Ruby, Java).

spelldump: 一个简单的命令行工具,用于从 ispell 或者 MySpell (OpenOffice内置绑定) 格式的字典中提取词条。当使用 wordforms时可用这些词条对索引进行定制.

indextool: 工具程序,用来转储关于索引的多项调试信息。此工具是从版本Coreseek 3.1(Sphinx 0.9.9-rc2)开始加入的。

mmseg: 工具程序和库,Coreseek用于提供中文分词和词典处理。

自动化命令 crontab -e

*/1 * * * * /bin/sh /usr/local/coreseek/bin/indexer -c /usr/local/coreseek/etc/csft_mysql.conf delta --rotate

*/5 * * * * /bin/sh /usr/local/coreseek/bin/indexer -c /usr/local/coreseek/etc/csft_mysql.conf --merge main delta --rotate --merge-dst-range deleted 0 0

30 1 * * * /bin/sh /usr/local/coreseek/bin/indexer -c /usr/local/coreseek/etc/csft_mysql.conf --all --rotate

以下任务计划的意思是:每隔一分钟执行一遍增量索引,每五分钟执行一遍合并索引,每天1:30执行整体索引。

 

9. 常用命令列表

启动后台服务(必须开启)

# /usr/local/coreseek/bin/searchd -c /usr/local/coreseek/etc/csft_mysql.conf

执行索引(查询、测试前必须执行一次)

# /usr/local/coreseek/bin/indexer -c /usr/local/coreseek/etc/csft_mysql.conf --all --rotate

执行增量索引

# /usr/local/coreseek/bin/indexer -c /usr/local/coreseek/etc/csft_mysql.conf delta --rotate

合并索引(为了防止多个关键字指向同一个文档加上--merge-dst-range deleted 0 0)

# /usr/local/coreseek/bin/indexer -c /usr/local/coreseek/etc/csft_mysql.conf --merge main delta --rotate --merge-dst-range deleted 0 0

后台服务测试

# /usr/local/coreseek/bin/search -c /usr/local/coreseek/etc/csft_mysql.conf aaa

关闭后台服务

# /usr/local/coreseek/bin/searchd -c /usr/local/coreseek/etc/csft_mysql.conf --stop


数据源配置关键选项

1. type:数据源类型

2. sql_host:数据库服务器

3. sql_port:数据库端口

4. sql_user:数据库用户名

5. sql_pass:数据库密码

6. sql_db:数据库名称

7. mysql_connect_flags:32 启用压缩协议

8. sql_query_pre:预查询  

sql_query_pre = SET NAMES utf8    # 设置字符集

sql_query_pre = SET SESSION query_cache_type=OFF    # 禁止mysql的查询缓冲,以获取最新的结果

9. sql_query:主查询选项,最多只能查询32个字段,字段的第一列必须是主键id或正整数值

10. sql_query_range:分区查询

sql_query_range = SELECT MIN(id),MAX(id) FROM documents

11. sql_range_step:分区查询步数,即每次查询多少数据

sql_range_step = 1000

12. sql_attr_uint:整数属性

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,293评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,604评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,958评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,729评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,719评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,630评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,000评论 3 397
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,665评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,909评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,646评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,726评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,400评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,986评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,959评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,197评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,996评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,481评论 2 342

推荐阅读更多精彩内容