移动互联网api设计实践

api quota perf design 过去一年时间里,都在做移动互联网下的API设计工作,所面对的情况可能是最具特色的了。如果你在尝试构架一整套的新的API供你的客户端使用,可以尝试以下的几点: 1)api所使用协议,要能够不怕被加js、加广告和各种代码。 各地的运营商,有习惯挂广告、加代码等等,要做的事情就是在客户端做各种解析判断。实践证明,这帮的设备是检测http协议的head头里的content-type,如果是html/text则会加,如果是text/json就不加了,所以,你。

2)api可视化 你的app上架了,后端也布好了。然后呢,就天天看下载量。但后端好坏一问三不知。所以在设计api时,要提前回答以下问题:
1.此时此刻,有多少个app正在调用这些api,每分钟多少个?
2.他们(api)有快?
3.能否很简单地通过浏览器快速debug?
4.能否快速禁止单个用户?

3)链路 在幅员辽阔的我国,总是一个地方到一个地方的IDC直接就ping不通(移动互联网下更甚)。于是需要花钱自己打通这些地方,没有专线,只有代理再代理。

4)api quota与perfcounter 对api进行quota限制,针对每个api每个人,都有限额。
这个限制的传统做法:
1.每天的上限调用次数。每天半夜清空,一天一个量累计。
2.每分钟的频度。这个防止有恶性的突发情况。
上述二者,缺一不可。
perfcounter用于对api的监控设计指标,如果一个api有异常,应当十分灵敏地得出结论,而不是误报连连。

神器monit监控报警设置手记

monit

系统监控工具monit是一款功能非常丰富的进程、文件、目录和设备的监测软件,用于Unix平台。它可以自动修复那些已经停止运作的程序,特使适合处理那些由于多种原因导致的软件错误。

安装 centos:

yum install monit
ubuntu:
apt-get install monit

使用 配置文件在/etc/monit.conf

配置发邮件的smtp服务器

set mailserver 111.111.111.111 USERNAME "xxx@xiaomi.com" PASSWORD "54chen54chen"

配置服务检测的周期

set daemon 30
30秒检查一次

配置报警邮件格式

set mail-format {
from: ALERT subject: $SERVICE $EVENT at $DATE
message: Monit $ACTION $SERVICE at $DATE on $HOST: $DESCRIPTION.
}

配置收报警的人

set alert 54chen@xiaomi.com with reminder on 3 cycles ;出问题时最多连续报3次

配置监控对象

check host webim-91 with address 192.168.1.2
if failed host www.miliao.com port 80 proto http and request "/test.html" for 2 times within 2 cycles then alert

其他 可以监控的类型有: CHECK PROCESS FILE FIFO DEVICE DIRECTORY HOST SYSTEM

帮助

man monit

Thrift快速入门实例

 thrift Thrift是Facebook的核心框架之一,使不同的开发语言开发的系统可以通过该框架实现彼此的通信,类似于webservice,但是Thrift提供了近乎变态的效率和开发的方便性,是webservice所不能比拟的。给分布式开发带来了极大的方便。但是这柄利器也有一些不完美。

安装thrift

1、./configure --with-boost=/usr/include
2、make
3、make install

定义接口文件

  1. vim chen.thrift  
  2.   
  3. #!/usr/local/bin/thrift --gen java  
  4. namespace java com.chen  
  5. service Hello{  
  6.         i32 hello()  
  7. }  

生成代码

  1. thrift --gen java chen.thrift   

要使用1.6的jdk 实现server代码:

  1. /** 
  2.  * @author 54chen(陈臻) [chenzhen@xiaomi.com cc0cc@126.com] 
  3.  * @since 2011-6-24 下午08:11:15 
  4.  */  
  5. package com.chen;  
  6.   
  7. import org.apache.thrift.TException;  
  8.   
  9. public class HelloImpl implements Hello.Iface {  
  10.   
  11.     public void HelloImpl() {  
  12.     }  
  13.     public int hello() throws TException {  
  14.         System.out.println("hello 54chen");  
  15.         return 0;  
  16.     }  
  17.   
  18. }  

通过下面的代码启动server

  1. TServerSocket serverTransport = new TServerSocket(7911);  
  2.        Hello.Processor processor = new Hello.Processor(new HelloImpl());  
  3.        Factory protFactory = new TBinaryProtocol.Factory(truetrue);  
  4.        TServer server = new TThreadPoolServer(processor, serverTransport, protFactory);  
  5.        System.out.println("Starting server on port 7911 ...");  
  6.   
  7.        server.serve();  

通过下面代码启动client

  1. TTransport transport = new TSocket("localhost"7911);  
  2.       TProtocol protocol = new TBinaryProtocol(transport);  
  3.       Hello.Client client = new Hello.Client(protocol);  
  4.       transport.open();  
  5.       System.out.println("Client calls hello()");  
  6.       client.hello();  
  7.       transport.close();  

Quercus记录:php使用连接池访问数据库

java php quercus 上周记录了如何用quercus建立混合型项目。 http://www.54chen.com/php-tech/quercus-notes-php-java-mixed-projects.html 这里来说说与数据库的访问,使用jndi得到连接池的好处。

JNDI (Java Naming and Directory Interface)是SUN公司提供的一种标准的Java命名系统接口,JNDI提供统一的客户端API,通过不同的访问提供者接口JNDI SPI的实现,由管理者将JNDI API映射为特定的命名服务和目录系统,使得Java应用程序可以和这些命名服务和目录服务之间进行交互。

正题 在quercus中可以随意使用mysql_connect与mysql_pconnect两个方法来连接数据库。
当在web.xml定义得有database相关的消息时,mysql_connect与mysql_pconnect都会自动忽略里面的参数设置,直接使用web.xml的定义。

添加jndi设置: vim WEB-INF/web.xml

  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <web-app  xmlns="http://caucho.com/ns/resin">  
  3.   <description>truth application</description>  
  4.   <database jndi-name="jdbc/mysql">  
  5.     <driver type="com.mysql.jdbc.Driver">  
  6.       <url>jdbc:mysql://192.168.1.5:3306/truth?useUnicode=true&amp;characterEncoding=utf-8</url>  
  7.       <user>你的用户名</user>  
  8.       <password>你的密码</password>  
  9.       <init-param useUnicode="true"/> <!--实践证明这个是不管用的,因为quercus写土了,全用的latin1字符集,后面再说-->  
  10.     </driver>  
  11.   </database>  
使用的是resin4,需要继续在web.xml的servlet段里增加:
  1. <init-param>  
  2.   <param-name>database</param-name>  
  3.   <param-value>jdbc/mysql</param-value>  
  4. </init-param>  
这里注意,param-value与上面的jndi-name对应,mysql_connnect函数在web.xml里有这个init-param的定义的时候,将使用对应的jndi的设置。由此可得到连接池的好处。

上面的例子只使用了jdbc的基础驱动,如果向下面的配置,自然就得到了pool: 例子1:

  1. <database>  
  2.   <jndi-name>jdbc/mysql</jndi-name>  
  3.   <driver> <type>com.mysql.jdbc.jdbc2.optional.MysqlConnectionPoolDataSource</type>  
  4.     <url>jdbc:mysql://localhost:3306/dbname</url>  
  5.     <user>username</user>  
  6.     <password>password</password>  
  7.     <init-param useUnicode="true"/>  
  8.   </driver>  
  9. </database>  

例子2:

  1. <database>  
  2.       <jndi-name>jdbc/mysql</jndi-name>  
  3.       <driver type="org.gjt.mm.mysql.Driver">  
  4.         <url>jdbc:mysql://localhost:3306/test</url>  
  5.         <user></user>  
  6.         <password></password>  
  7.        </driver>  
  8.        <prepared-statement-cache-size>8</prepared-statement-cache-size>  
  9.        <max-connections>20</max-connections>  
  10.        <max-idle-time>30s</max-idle-time>  
  11.      </database>  

这些简单的配置,都可以让php轻松跑在连接池上。 问题所在: quercus写土了,没有在用户设置为unicode的时候来解析用户的输入,到处是hard code的latin1。(本来在GAE里使用这东西的人挺多的,可惜吧,AGE被盾了,然后quercus反馈latin1问题的人也不多,唉。)

  1. com.caucho.quercus.lib.db.JdbcConnectionResource: 94  348  
  2. com.caucho.quercus.lib.db.Mysqli:229  
上面三处修改为utf8即可。

Quercus记录:php和java的混合型项目建立手记

创业公司参与项目的人口众多、背景不一,目前市场上的主流方向为php与java,很多时候java工程师恨铁不成钢,php工程师也无可奈何。于是便有了此文,讲述如何使用quercus创建php java混合型项目。

quercus是什么? quercus是Caucho公司针对php语言的java实现,100%完成了php5的解析。是resin内建支持的功能。同时,因为使用了resin,使得php可以很容易得到连接池、分布式session、负载均衡等功能。使用resin的php项目可以更加安全,不存在很多fastcgi的问题。

性能如何? 官方:用mediawiki与drupal来做实验,要比mod_php快4倍。
有一个编译选项,在resin专业版里支持,可以把php转成java class,得到更高性能。

新建一个java项目混合php项目 web.xml是关键,里面声明了*.php文件的访问都以com.caucho.quercus.servlet.QuercusServlet来执行。

  1. <?xml version="1.0" encoding="UTF-8"?>  
  2. <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
  3.     xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"  
  4.     xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"  
  5.     id="WebApp_ID" version="2.5">  
  6.     <display-name>testquercus</display-name>  
  7.     <welcome-file-list>  
  8.         <welcome-file>index.html</welcome-file>  
  9.         <welcome-file>index.php</welcome-file>  
  10.     </welcome-file-list>  
  11.     <servlet>  
  12.         <servlet-name>Quercus Servlet</servlet-name>  
  13.         <servlet-class>com.caucho.quercus.servlet.QuercusServlet</servlet-class>   
  14.     </servlet>  
  15.     <servlet-mapping>  
  16.         <servlet-name>Quercus Servlet</servlet-name>  
  17.         <url-pattern>*.php</url-pattern>  
  18.     </servlet-mapping>   
  19. </web-app>  

所有的php文件放在webapp下,所有的java文件还放到java目录里。

如何混合java到php中?
在java目录新建类Test54Chen,生成后位置:
WEB-INF/classes/com/chen/FrameWork.class

  1. /** 
  2.  * @author 54chen(陈臻) [chenzhen@xiaomi.com cc0cc@126.com] 
  3.  * @since 2011-10-25 下午08:40:49 
  4.  */  
  5. package com.chen;  
  6.   
  7. public class FrameWork {  
  8.     public String go(String who) {  
  9.         return who + " gogogo!";  
  10.     }  
  11. }  
在webapp新建php文件:
test.php
  1. <?php  
  2. import com.chen.FrameWork;  
  3. $f = new FrameWork();  
  4. var_dump($f->go("ohohoh"));  
  5. ?>  
配置到resin中:
目标文件夹指到webapp。

访问:test.php

截图:
1.整个项目的情况 quercus 2.访问的结果 quercus php java 下一记:如何利用java做连接池提供给php使用。