Previous notes:
I believe that when you engage in the development of the iOS push service, you will use the Javapns API directly to implement it, and the debugging is direct to Apple's APNs service (product/beta). Very few people write a APNs service, and that's the case. Just at the time I was faced with some special application scenarios, in order to test the performance of the service and debugging features convenient, specifically wrote the APNs pile service (in fact, the main reason is the iphone test machine, was team leader "occupy" for their own use, ⊙﹏⊙ b Khan). Write an article about APNs pile service, in order to commemorate the lost "youth", but also hope to help readers.
Some things in retrospect, vivid, clear and abnormal, as if it happened yesterday. A year ago, the development of iOS APNs push back-end service, vomiting blood three liters ...
Adhering:
The previous article, see: Apple's APNs-pile push Service implementation (1)
This paper briefly introduces some basic concepts and implementation principles of API for APNs Protocol/certificate Management/jsse.
Requirements Analysis:
Understand and analyze requirements from a developer's perspective. The features and performance tests for message push for iOS can be broadly categorized as follows:
1). Performance index of Push platform QPS/RT
2). Bad Device token impact assessment of the service
3). Assessment of the impact of certificates on services
4). Push reliability evaluation (push weak ACK mechanism, drop message and message repetition between the compromises)
By logging to evaluate the quality of qps/rt and Services, a blacklist mechanism is introduced to simulate the impact evaluation of bad device tokens on the push service. Technical Analysis:
Technical Analysis:
Understanding of the APNs service and its own functional/performance testing needs:
1). APNs Push service is implemented with SSL long connection/binary stream/async, which pursues the throughput of push message.
2). APNs supports v1/v2 two types of binary protocols, and when an exception is encountered, the default behavior of APNs is different.
3). APNs client is a one-way authentication for TSL (SSL) (client carrying certificate, server-side trust check).
Combined with the positioning of the pile, we use one Connection Per thread of thread pool mode to simulate processing it, on the one hand can basically meet the demand, on the other hand to achieve efficiency and simplicity. At the same time, in order to facilitate testing, the server shuts down the client authentication mechanism.
Service implementations:
The realization process of APNS simulation piles
1). Server-Side Certificate Introduction
Keytool-genkey-v-alias ssl-server-keyalg rsa-keystore/server_ks-storepass server-keypass 123456-dname "CN=Unknow N
Build effect
2). Custom TrustManager Implementation Class
Private class Myx509trustmanager implements X509trustmanager {@Override public x509certificate[] Getacceptedissuers () { return null; }//Authentication to the server-side certificate, throwing an exception indicates that the @Override public void checkservertrusted (x509certificate[] chain, String authtype) throw S certificateexception {}//authenticates the client certificate and throws an exception indicating that it does not pass @Override public void checkclienttrusted (x509certificate[] chain, String authtype) throws certificateexception {}};
Commentary: This side provides an empty implementation , no verification of the client's certificate
3). Create a Sslserversocket code snippet
Sslcontext CTX = sslcontext.getinstance ("SSL");//*) Create Keymanagerfactory class instance keymanagerfactory KMF = Keymanagerfactory. G Etinstance (Keymanagerfactory.getdefaultalgorithm ());//*) Initialize KeyStore, Key_password on this side is "123456" KeyStore ks = Keystore.getinstance (Keystore.getdefaulttype ()); Ks.load (ApnsStubServer.class.getResourceAsStream ("/server_ks") , null), Kmf.init (KS, Key_passwor.tochararray ()),//*) Initialization of Sslcontext class Ctx.init (Kmf.getkeymanagers (), New Trustmanager[] {new Myx509trustmanager ()}, New SecureRandom ()),//*) Sslserversocket generation Sslserversocket ServerSocket = (Sslserversocket) ctx. Getserversocketfactory (). Createserversocket (ServerPort); Serversocket.setreuseaddress ( true);//*) Set client authentication switch off Serversocket.setneedclientauth (false);
Commentary: Put the server_ks code in the Classpath directory , while the key_password here is "123456", instead of the KeyStore password "server", Notice the difference between Keypass and Storepass.
4). Service-Side Connection processing code
One Connection Per thread mechanism executorservice workerpools = Executors.newcachedthreadpool (); while (true) {final Socke T clisocket = sslserversocket.accept (); Workerpools.execute (New Runnable () {@Override public void run () {onhandle (clisocket); } });}
Commentary: ServerSocket is used to accept client connections and put them into a work pool to handle
The Onhandle function is defined as follows:
private void Onhandle (Socket clisocket) {Devicetokenmanager DTM = Apnsstubcontroller.getdevicetokenmanager ();
DataInputStream dis = new DataInputStream (Clisocket.getinputstream ()); int ch = 0; while (ch = dis.read ())! =-1) {ivresult<apnsmessage> result = apnsprotocolutility.readmessage (ch, dis); Apnsmessage message = Result.getvalue (); Messages belonging to different versions are distributed and processed if (APNSVERSION.APNS_BINARY_PROTOCOL_V1 = = Message.getversion ()) {//*) if they belong to bad device T Oken blacklist if (Dtm.judgebaddevicetoken (Message.getdevicetoken ())) {break; } printmessage (message); } else if (Apnsversion.apns_binary_protocol_v2 = = Message.getversion ()) {//*) if it belongs to the bad device token blacklist if (d Tm.judgebaddevicetoken (Message.getdevicetoken ())) {///8 is a token error, which is bad device token apnsprotocolutility. WRI Teresponse (8, Message.getidentifier (), Clisocket.getoutputstream ()); Break } printmessage (message); } }}
5 ). Blacklist introduction and Interface Definition
specified by an external blacklist file
public class Devicetokenmanager {//Initialize public void init (Properties prop) for configuration parameters; Determine if the bad device token is public boolean judgebaddevicetoken (String devicetoken); Load the bad device token list private void Loadbaddevicetokenfile (String filename);
Summary: The difficulty lies in Jsse and certificate understanding, as for APNs network protocol, processing or relatively simple.
APNs Push Service Platform:
For the APNs push service platform, there are some optimization techniques, this side is not in-depth, only from the personal point of view to describe a few.
1). For gateway.push.apple.com IP address resolution, Select the service IP with the shortest RRT time to connect
2). introduce queue asynchronous/build Daddevicetoken warehouse
As a push service, for push requests, make a simple check (message format is legal/is bad device token). The message is then stored in the queue and slowly digested by the back-end worker . No longer waits for the real APNs service feedback (APNs service weak ACK mechanism ) to return the result immediately ( allowing a certain degree of push success false positives rate).
Build your own bad Device token repository , one party from the feedback service acceptance, and one party from the APNs push response result collection.
Postscript:
It is a pity to feel that I am still not saying what I want to express. In any case, I still hope to have some help to the reader, for me, it is full of memories. Fighting, let it go!!!
Implementation of APNs pile push service in mobile internet Combat--apple (2)