Andoird想支持emoji表情的曲折经历(未完待续)

想支持emoji表情的曲折经历

前奏:android post到java后台的数据,后台使用String存储,通过hibernate insert到mysql5.1数据库,会看到有报错。
java.sql.SQLException: Incorrect string value: '\xF0\x9F\x92\x94' for column 'content' at row ……
就是不支持呗。我本地电脑是mariadb5.6,支持但是我使用的是utf8,它不会报错,会插入进去,但是数据库客户端和java都不支持,我也看不到,不知道是正确,或者不正确的。反正能存不报错。

也许大家都是分工明确的,所以从网上看到的教程里面,就只有移动端或者服务端,没有一个人能给出一个完整的解决方案。
本文后面会给出一个解决方案。
关于emoji的起源之类的,就去网上找吧。太多了,都是复制粘贴的。
为什么会不支持emoji?
因为它不是gbk,也不是utf8,而是utf8mb编码(utf8的超集)。同时它开始于ios,所以android上没有。。。
首先说支持emoji的两种方法:
一、前端显示的方法
1. 字库,用支持utf8mb的新字库。
2. 做图片映射,就是自己把这些表情代码找出来,并且替换成一些标记,比如[emoji]0x1f604[/emoji]。
二、后端传输及存储方式(java web)
1. 数据库存储utf8mb
2. 存储自定义标记,使用时再转换
优劣:
第一种方法:需要升级mysql数据库,mysql java驱动,但是对于多平台应用,不太合适。而且当前而言,utf8mb的使用并没有那么广泛。而且——我已经测试过了,tomcat7,jdk7,在windows环境下,存储后是????,并不能正确存储。而在linux上可以正确存储。可能是两个操作系统的编码问题。这样开发就不方便了。
第二种方法:不需要对现有环境做改变,但是需要自己写一些处理方法,识别出这些字符,做替换存储,使用时,再反向替换(显示为图片,比如web端和android端)。好处是,可以多平台通用。
我最终的方法是选择第二种,下面先讲第一种方法的曲折经历。
一、mysql数据库升级遇到的内存不足问题
mysql数据库升级 5.1到5.6 同时修改表支持utf8mb4
因为要给Andorid移动应用添加一个emoji表情支持。而网上大多说法是emoji是4个字节的utf8,现在服务器使用的都是3个字节的utf8。mysql从5.5.+的某个版本开始支持utf8mb4,也就是可以存4个字节的了。但是我一直在想在java后台怎么处理?
网上还有很多文章(X度能够搜出来的东西,基本上都是一个模板,内容都是Ctrl+V的),说的都是怎么在mysql数据库里面存emoji表情,那么就需要使用mysql5.5.+的那个开始支持的版本了,我去官网看了下,所以决定使用mysql5.6。
从昨天晚上的这一刻开始,我就给自己挖好了坑,并且舒舒服服地跳进去了。
服务器配置:X里云服务器。1核cpu,512M内存,20G硬盘,一个月50块,很贵的。
我在安装的时候就已经很困惑了,为什么mysql5.1和mysql5.6的安装包大小差距这么大,5.1只有10+m,5.6有70m。可能真的是年份久远了吧。
我在开发的时候其实一直使用mariadb5.6的。只不过在centos上,mysql安装更方便一些。看来,也许我的服务器也应该换了。
开始安装:
采用yum安装,非编译源码。编译源码太麻烦了。虽然其实还好了~~~
1. 备份数据库,这个自己动手,我就不多说了。
2. 卸载以前的版本(升级其实也不麻烦):yum remove mysql(慎用)
3. 从mysql官网下载yum源(安装方便):wget http://dev.mysql.com/get/mysql-community-release-el5-5.noarch.rpm
这个是支持redhat6.x版本的,可以自己去下载其它服务器版本的 http://dev.mysql.com/downloads/repo/yum/
4. 安装yum源:rpm -Uvh mysql-community-release-el5-5.noarch.rpm
5. 安装mysql:yum install mysql-server -y
这里会去下载安装包,等好久。学校网速在烂了。
而且大半夜熄灯后,我用手机2G网络ssh连接到服务器等着下载完成是多么痛苦的一件事情。而且今天发现,中午吃完饭的时候,网速貌似是最快的……
6. yum安装的好处就是什么都不用管,坏处就是,自定义性差,但是配置文件还是可以自己修改的。
7. 启动mysql(yum安装,服务会自己装好的,而且有环境变量,什么都不用配置,想我当年编译源码,搞了很久才好):service mysqld start

[root@AY140416152603506d4cZ ~]# service mysqld start
Initializing MySQL database: 2014-11-14 13:46:19 0 [Warning] TIMESTAMP with implicit DEFAULT value is deprecated. Please use --explicit_defaults_for_timestamp server option (see documentation for more details).
2014-11-14 13:46:19 5502 [Warning] No argument was provided to --log-bin, and --log-bin-index was not used; so replication may break when this MySQL server acts as a master and has his hostname changed!! Please use '--log-bin=AY140416152603506d4cZ-bin' to avoid this problem.
2014-11-14 13:46:19 5502 [Note] InnoDB: Using atomics to ref count buffer pool pages
2014-11-14 13:46:19 5502 [Note] InnoDB: The InnoDB memory heap is disabled
2014-11-14 13:46:19 5502 [Note] InnoDB: Mutexes and rw_locks use GCC atomic builtins
2014-11-14 13:46:19 5502 [Note] InnoDB: Memory barrier is not used
2014-11-14 13:46:19 5502 [Note] InnoDB: Compressed tables use zlib 1.2.3
2014-11-14 13:46:19 5502 [Note] InnoDB: Using Linux native AIO
2014-11-14 13:46:19 5502 [Note] InnoDB: Using CPU crc32 instructions
2014-11-14 13:46:19 5502 [Note] InnoDB: Initializing buffer pool, size = 10.0M
2014-11-14 13:46:19 5502 [Note] InnoDB: Completed initialization of buffer pool
2014-11-14 13:46:19 5502 [Note] InnoDB: The first specified data file ./ibdata1 did not exist: a new database to be created!
2014-11-14 13:46:19 5502 [Note] InnoDB: Setting file ./ibdata1 size to 12 MB
2014-11-14 13:46:19 5502 [Note] InnoDB: Database physically writes the file full: wait...
2014-11-14 13:46:19 5502 [Note] InnoDB: Setting log file ./ib_logfile101 size to 48 MB
2014-11-14 13:46:21 5502 [Note] InnoDB: Setting log file ./ib_logfile1 size to 48 MB
2014-11-14 13:46:22 5502 [Note] InnoDB: Renaming log file ./ib_logfile101 to ./ib_logfile0
2014-11-14 13:46:22 5502 [Warning] InnoDB: New log files created, LSN=45781
2014-11-14 13:46:22 5502 [Note] InnoDB: Doublewrite buffer not found: creating new
2014-11-14 13:46:22 5502 [Note] InnoDB: Doublewrite buffer created
2014-11-14 13:46:22 5502 [Note] InnoDB: 128 rollback segment(s) are active.
2014-11-14 13:46:22 5502 [Warning] InnoDB: Creating foreign key constraint system tables.
2014-11-14 13:46:22 5502 [Note] InnoDB: Foreign key constraint system tables created
2014-11-14 13:46:22 5502 [Note] InnoDB: Creating tablespace and datafile system tables.
2014-11-14 13:46:22 5502 [Note] InnoDB: Tablespace and datafile system tables created.
2014-11-14 13:46:22 5502 [Note] InnoDB: Waiting for purge to start
2014-11-14 13:46:22 5502 [Note] InnoDB: 5.6.21 started; log sequence number 0
2014-11-14 13:46:23 5502 [Note] Binlog end
2014-11-14 13:46:23 5502 [Note] InnoDB: FTS optimize thread exiting.
2014-11-14 13:46:23 5502 [Note] InnoDB: Starting shutdown...
2014-11-14 13:46:24 5502 [Note] InnoDB: Shutdown completed; log sequence number 1625977[/p][p=30, 2, left]2014-11-14 13:46:24 0 [Warning] TIMESTAMP with implicit DEFAULT value is deprecated. Please use --explicit_defaults_for_timestamp server option (see documentation for more details).
2014-11-14 13:46:24 5524 [Warning] No argument was provided to --log-bin, and --log-bin-index was not used; so replication may break when this MySQL server acts as a master and has his hostname changed!! Please use '--log-bin=AY140416152603506d4cZ-bin' to avoid this problem.
2014-11-14 13:46:24 5524 [Note] InnoDB: Using atomics to ref count buffer pool pages
2014-11-14 13:46:24 5524 [Note] InnoDB: The InnoDB memory heap is disabled
2014-11-14 13:46:24 5524 [Note] InnoDB: Mutexes and rw_locks use GCC atomic builtins
2014-11-14 13:46:24 5524 [Note] InnoDB: Memory barrier is not used
2014-11-14 13:46:24 5524 [Note] InnoDB: Compressed tables use zlib 1.2.3
2014-11-14 13:46:24 5524 [Note] InnoDB: Using Linux native AIO
2014-11-14 13:46:24 5524 [Note] InnoDB: Using CPU crc32 instructions
2014-11-14 13:46:24 5524 [Note] InnoDB: Initializing buffer pool, size = 10.0M
2014-11-14 13:46:24 5524 [Note] InnoDB: Completed initialization of buffer pool
2014-11-14 13:46:24 5524 [Note] InnoDB: Highest supported file format is Barracuda.
2014-11-14 13:46:24 5524 [Note] InnoDB: 128 rollback segment(s) are active.
2014-11-14 13:46:24 5524 [Note] InnoDB: Waiting for purge to start
2014-11-14 13:46:24 5524 [Note] InnoDB: 5.6.21 started; log sequence number 1625977
2014-11-14 13:46:24 5524 [Note] Binlog end
2014-11-14 13:46:24 5524 [Note] InnoDB: FTS optimize thread exiting.
2014-11-14 13:46:24 5524 [Note] InnoDB: Starting shutdown...
2014-11-14 13:46:26 5524 [Note] InnoDB: Shutdown completed; log sequence number 1625987[/p][p=30, 2, left]PLEASE REMEMBER TO SET A PASSWORD FOR THE MySQL root USER !
To do so, start the server, then issue the following commands:
 /usr/bin/mysqladmin -u root password 'new-password'
 /usr/bin/mysqladmin -u root -h AY140416152603506d4cZ password 'new-password'
Alternatively you can run:
 /usr/bin/mysql_secure_installation
which will also give you the option of removing the test
databases and anonymous user created by default. This is
strongly recommended for production servers.
See the manual for more instructions.
Please report any problems at [url=http://bugs.mysql.com/]http://bugs.mysql.com/[/url]
The latest information about MySQL is available on the web at
 [url=http://www.mysql.com]http://www.mysql.com[/url]
Support MySQL by buying support/licenses at [url=http://shop.mysql.com]http://shop.mysql.com[/url]
Note: new default config file not created.
Please make sure your config file is current
WARNING: Default config file /etc/my.cnf exists on the system
This file will be read by default by the MySQL server
If you do not want to use this, either remove it, or use the
--defaults-file argument to mysqld_safe when starting the server
 [ OK ] 
MySQL Daemon failed to start.
Starting mysqld: [FAILED]


 
8. 解决问题:看看上面,有警告,但是没有错误。以这个错误去X度搜是不会有太多收获的,而且都是一模一样的内容,可谓千篇一律。还是看日志,加经验分析最重要了。
8.1 警告的信息加上以后还是错
就下面这样一行错,没有什么其它提示。
8.2 mysql的日志默认在/var/log/mysqld.log
进去看看,发现只有两条信息

 
141114 13:18:23 mysqld_safe Starting mysqld daemon with databases from /var/lib/mysql
 141114 13:18:24 mysqld_safe mysqld from pid file /var/run/mysqld/mysqld.pid ended

 

   一条启动的,一条失败的,没有别的提示。
8.3 因最近一直想把网站用ssh框架重写,再添加一些功能,所以一直在考虑,这样的服务器,能跑得动吗?java那么占内在。第一个想到的就是内存不足。于是关闭了apache服务器,tomcat服务器,还是不行。一样的错
8.4 想……想不出来,因为配置文件本身没有错,使用的是默认值。默认值,必然也是官方推荐,不会和我的环境一样,所以想在配置文件my.cnf中添加一些参数限制内存试试。
my.cnf
# Remove leading # and set to the amount of RAM for the most important data
# cache in MySQL. Start at 70% of total RAM for dedicated server, else 10%.



意思是说,设置mysql的缓存,如果是专用服务器,设置为内存的70%,其它服务器的设置为10%
它默认值是128M。
我设置了好几个一直不行,直到我设置成10M。。。
我们来看看它占用了多少。
没有开启mysql服务时:


[root@AY140416152603506d4cZ ~]# service mysqld stop
Stopping mysqld: [ OK ]
[root@AY140416152603506d4cZ ~]# free -m 
 total used free shared buffers cached
Mem: 490 61 429 0 1 15
-/+ buffers/cache: 45 445
Swap: 0 0 0


开启mysql服务后:
[root@AY140416152603506d4cZ ~]# service mysqld start
Starting mysqld: [ OK ]
[root@AY140416152603506d4cZ ~]# free -m
 total used free shared buffers cached
Mem: 490 484 6 0 0 13
-/+ buffers/cache: 469 20
Swap: 0 0 0


很明显,占用了400多M。我总共服务器才512M,我还要跑apache和tomcat呢。java也是个吃内存的大家伙。
这个时候,唯一想到的词就是——“优化”。也是这一次,我感觉到这个词的重量了。
9. 降低mysql内存
修改这三个参数的大小(在my.cnf配置文件中)
performance_schema_max_table_instances、table_definition_cache、table_open_cache。
默认值如下:
performance_schema_max_table_instances 12500
table_definition_cache 1400
table_open_cache 2000


解释:
performance_schema_max_table_instances :The maximum number of instrumented table objects.
table_definition_cache:
The number of table definitions (from .frm files) that can be stored in the definition cache
table_open_cache:The number of open tables for all threads.
修改为:
performance_schema_max_table_instances=200
table_definition_cache=200
table_open_cache=128
 

内存使用量会下降不少。再看看。

 
[root@AY140416152603506d4cZ ~]# free -m
 total used free shared buffers cached
Mem: 490 134 356 0 3 35
-/+ buffers/cache: 95 395
Swap: 0 0 0


看来这样子问题就算暂时解决了,深度优化这种事情,如果网站做大了,确实是需要的。
10. 修改默认密码:
10.1 我是卸载后重装,发现我原来的密码还在。
10.2 #mysql -uroot -p 回车没有密码,直接就能进去。

 
use mysql;
 update user set PASSWORD = PASSWORD('******') where USER='root' and HOST='localhost';


 12. 还原数据库
这个自己来吧,我就不说了。可能会需要一些时间。
13. 修改数据库字符集为utf8mb4

14. apache2可以启动了,tomcat启动了,mysql启动了。但是网站进不去了。猜测是mysqli连接器版本不够。果然,以前的版本是Client API header version 5.0.96
去mysql官网看了下,php的没有可以直接更新的连接器,只能更新php版本了。5.4以上的应该就ok。连接方式是mysqlnd

二、php版本升级遇到的编译问题:mysql_config not found configure: error: Please reinstall the mysql distribution
php从5.3升级到5.6
因为升级了mysql,而php是之前编译的,所以扩展连接不上了,需要升级。
编译参数(错误的)
./configure --prefix=/usr/local/php --with-config-file-path=/usr/local/php/etc --with-apxs2=/usr/local/apache2/bin/apxs --with-mysql=mysqlnd --with-mysqli=mysqlnd --with-pdo-mysql=mysqlnd --with-libxml-dir=/usr/local/libxml2/ --with-png-dir=/usr/local/libpng/ --with-jpeg-dir=/usr/local/jpeg8/ --with-freetype-dir=/usr/local/freetype/ --with-gd --with-zlib-dir=/usr/local/zlib/ --with-mcrypt=/usr/local/libmcrypt/ --with-mysqli=/usr/local/mysql/bin/mysql_config --enable-soap --enable-mbstring=all --enable-sockets



周六一个上午都在弄这个,但是还是没有解决,按照官网的说法,使用mysqlnd连接,不需要预先安装mysql的,但是又报这个错,而且我的mysql已经启动就起来了。
修改后的编译参数(错误的):

./configure --prefix=/usr/local/php --with-config-file-path=/usr/local/php/etc --with-apxs2=/usr/local/apache2/bin/apxs --with-mysql=/usr --with-mysqli=/usr/bin/mysql_config --with-pdo-mysql=/usr --with-libxml-dir=/usr/local/libxml2/ --with-png-dir=/usr/local/libpng/ --with-jpeg-dir=/usr/local/jpeg8/ --with-freetype-dir=/usr/local/freetype/ --with-gd --with-zlib-dir=/usr/local/zlib/ --with-mcrypt=/usr/local/libmcrypt/ --with-mysqli=/usr/local/mysql/bin/mysql_config --enable-soap --enable-mbstring=all --enable-sockets 
使用这个参数后,又找不到configure: error: Cannot find libmysqlclient under /usr



但是, libmysqlclient 明明是安装在/usr/lib64/mysql下面的,后来在网上查了一下,貌似configure脚本的这个--with-mysql参数在RHEL5.3下有问题。
所以,索性搞两个软链接,问题解决
ln -s /usr/lib64/mysql/libmysqlclient.a /usr/lib/libmysqlclient.a 
ln -s /usr/lib64/mysql/libmysqlclient_r.a /usr/lib/libmysqlclient_r.a

 

再次执行,又出错
checking for mysql_close in -lmysqlclient... no
checking for mysql_error in -lmysqlclient... no



良久良久,没有解决。。。
可能的最大问题就是我使用的是yum的方式安装的mysql,所以会出现各种找不到的问题。
然后又出现 mysql_config not found configure: error: Please reinstall the mysql distribution
实在是不想再编译了。。
失败……
后来……
发现其实上面只是多一个参数。。。。--with-mysqli=/usr/local/mysql/bin/mysql_config
应该是(正确的)
./configure --prefix=/usr/local/php --with-config-file-path=/usr/local/php/etc --with-apxs2=/usr/local/apache2/bin/apxs --with-mysql=mysqlnd --with-mysqli=mysqlnd --with-pdo-mysql=mysqlnd --with-libxml-dir=/usr/local/libxml2/ --with-png-dir=/usr/local/libpng/ --with-jpeg-dir=/usr/local/jpeg8/ --with-freetype-dir=/usr/local/freetype/ --with-gd --with-zlib-dir=/usr/local/zlib/ --with-mcrypt=/usr/local/libmcrypt/ --enable-soap --enable-mbstring=all --enable-sockets --disable-fileinfo



但是又遇到新问题 虚拟内存耗尽 virtual memory exhausted: Cannot allocate memory
官网有解决方法 :https://bugs.php.net/bug.php?id=48809
Adding --disable-fileinfo to ./configure solves the problem.
最终还是把php5.6安装成功了。
但是数据库用的是5.0。按照这个理论,其实也可以用5.6的,但是我真的不想再折腾了。

三、误操作,删除了服务器数据库和数据文件
这个操作直接导致我的网站挂了……挂了好几天……

四、装虚拟机,配置环境,测试为什么在windows下不能存储emoji
1. 把mariadb从5.5(基于mysql5.6)升级到10.0(基于mysql5.6),理论来说都没有问题的。但是我还是试了一下,存储失败。在数据库里面看到的就是?
2. 在linux上成功的情况是,这些字符是看不见的,但传到手机上时就会看到emoji表情。所以判定第1条是失败。
3. 装虚拟机,配置环境,安装mysql5.6,tomcat,jdk,程序。直到启动后,再测试,没有问题,可以保存成功。
4. 然后使用windows的tomcat,linux的mysql。还是不能正确存储。
结论是,虽然可以使用mysql存储,但是却会因为环境的改变而发生变化,不稳定。

五、服务器还原我原来的mysql和php(这个是因为我有跑其它程序)
1. 以前使用过yum安装httpd,php,mysql,正常可用的。
2. 以前的以前mysql和php和apache都是编译源码安装的,不会出现问题。
3. 但是现在使用yum安装的却不能用。看来linux下用源码安装会比较靠谱
4. mysql5.0和php5.3源码安装成功。
5. 然后发现其实上面只是多一个参数。。。。--with-mysqli=/usr/local/mysql/bin/mysql_config
第一种方法,尽于此,不再做过多解释。不使用这个方法。

六、解决方案:
使用第二种方法:
请期待下一篇文章:


作者的论坛原文地址:

Andoird想支持emoji表情的曲折经历(未完待续)
http://bbs.vpigirl.com/forum.php?mod=viewthread&tid=498
(出处: 心惊变 回忆的路上,时间变得好慢!)


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值