Dubbo when the token service is turned on, using the cluster fault tolerance policy is failoverclusterinvoker, and when a service call fails to be transferred and another server is retried, a token invalid error occurs and provider denies the service call.
Reason:
Consumer end:
1, Com.alibaba.dubbo.rpc.cluster.support.failoverclusterinvoker#doinvoke:
for (int i = 0; i < len; i++) { //re-Select when retrying, avoiding retries when the Invoker list has changed. //Note: If the list changes, the invoked judgment will be invalidated because the invoker example has changed if (i > 0) { checkwheatherdestoried (); copyinvokers = list (invocation); //re-check checkinvokers (copyinvokers, invocation); } invoker<t> invoker = select (loadbalance, invocation, copyinvokers, invoked); invoked.add (Invoker); rpccontext.getcontext (). Setinvokers ((List) invoked); try { if (le != null && logger.iswarnenabled ()) { logger.warn (" although retry the method " + invocation.getmethodname () + " in the service " + getinterface (). GetName () + " was successful by the provider " + invoker.geturl (). GetAddress () + ", but there have been failed providers " + providers + " (" + providers.size ( ) + "/" + copyinvokers.size () + ") from the registry " + directory.geturl (). GetAddress () + " on the consumer " + Netutils.getlocalhost () + " using the dubbo version " + version.getversion () + " . last error is: " + le.getmessage (), le); } return result; } catch (rpcexception e) { if (E.isbiz ()) { // biz exception. throw e; } le = e; } catch ( Throwable e) { le = new rpcexception (E.getmessage (), e); } finally { providers.add (Invoker.geturl (). getAddress ()); }2, com.alibaba.dubbo.rpc.protocol.abstractinvoker# invoke rpcinvocation invocation = (rpcinvocation) inv; invocation.Setinvoker (This); if (attachment != null && attachment.size () > 0) { invocation.addattachmentsifabsent (attachment) //add relevant parameters to the attachment attachments, such as token } map< String, string> context = rpccontext.getcontext (). Getattachments (); if (context != null) { invocation.addattachmentsifabsent (context); }3, addattachmentsifabsent realization: public void Setattachmentifabsent (String key, string value) { if (Attachments == nulL) { attachments = new HashMap<String, String> (); } if (! attachments.containskey (key)) { //key does not exist when the assignment is made, Therefore cannot overwrite operation attachments.put (Key, value); } }
Service provider:
Public class tokenfilter implements filter { public result invoke (INVOKER<?>&NBSP;INVOKER,&NBSP;INVOCATION&NBSP;INV) throws rpcexception { string token = invoker.geturl (). GetParameter (Constants.token_key); if (Configutils.isnotempty (token)) { Class<?> servicetype = invoker.getinterface (); map<string, string> attachments = inv.getattachments ();// Parsing attachments string remotetoken = attachments == null ? null : attachments.get (Constants.TOKEN_KEY); if (! token.equals (remotetoken)) { throw new rpcexception ("Invalid token! forbid invoke remote service " + serviceType + " method " + inv.getmethodname () + "() from consumer " + rpccontext.getcontext (). Getremotehost () + " to provider " + rpccontext.getcontext (). Getlocalhost ()); } } return invoker.invoke (inv); }}
Through the above code analysis, when the consumer calls the Service party service timeout failed to re-connect, to re-connect the invoker token does not overwrite the last Invoker token, and the server compared to token when compared to attachment, and then appear token Invalid error. The equivalent of a failed re-connection is invalid.
Error phenomena:
1, the request time-out, at this time token is consistent
telnet=invoke,status,replacetoken&timeout=1000×tamp=1418813410249&token=020f16e2-e060-4c85-a31a-017aa0ee268c&version=1.0, cause:waiting server-side response timeout. Start time:2014-12-17 21:42:26.735, end time:2014-12-17 21:42:27.736, client elapsed:0 MS, server elapsed:1001 MS, Tim eout:1000 MS, Request:request [id=27484, version=2.0.0, Twoway=true, Event=false, Broken=false, data=RpcInvocation [...] ..., attachments={token=............020f16e2-e060-4c85-a31a-017aa0ee268c,
。。。。。。。
2, failure to re-connect, at this time the attachment token and URL inconsistencies
............. &pid=29465&revision=1.0.1&side=consumer&status=spring,load&telnet= invoke,status,replacetoken&timeout=1000×tamp=1418813410249
&token=0f3103ad-ac7b-4906-897c-b51e69ab3b96&version=1.0 and Rpcinvocation [...], and .................. ...],
attachments={token=020f16e2-e060-4c85-a31a-017aa0ee268c,
。。。。。。。
3. Token invalid appears
Com.alibaba.dubbo.rpc.RpcException:Invalid token! Forbid invoke remote service interface
Dubbo Token Invalid