關於webapi調用wcf併發假死的分析

原來IDFA(IOS推廣獲取到用戶IOS手機的惟一標識,若是不刷機的話跟安卓的IMEI同樣)在公司正常的頁面是公用用一個網站和數據庫的。mysql

起初懷疑併發數太多,把數據庫鏈接池的數量從一百設置到三百,確實有點反應,可是支持不到一天就又報錯。web

 

 

 

查看了webapi鏈接wcf不少都超時,一臺api和wcf不夠用而後叫運維從一臺服務器擴展到多臺,報錯的頻率比原來低了。sql

看到網上設置是否是由於WCF不是多線程的緣由,而後形成等待超時,而後設置了WCF支持多線程,可是仍是沒有多少做用。數據庫

[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerSession, ConcurrencyMode = ConcurrencyMode.Multiple)]api

 

 

還有懷疑天天的寫入調用太頻繁,把寫入的數據改成消息隊列,而不是開線程的插入,否則短期內線程多開太多,會形成服務器線程異常。服務器

 

懷疑併發太多形成數據庫堵塞(最大一個表的數據達600W)。網絡

 

 

常常報錯,影響到原有的公司正常業務,可是看了數據一天請求也只不過一二十萬的請求量,也不至於這麼不抗壓,抱着懷疑的心態跟上級申請把這塊相關,另一個緣由是其餘項目組也要用到這個項目,推广部以爲如今的網站常常報錯,也支撐不起另一個項目的IDFa的訪問量,因此考慮獨立一個數據庫出來,而後在本地IIS和測試環境(一臺真實服務器拆分下來分開多臺的虛擬服務器)。多線程

而後懷疑是否是跟以前最開始的mysql數據庫版本不兼容,形成的緣由。由於網上有說這方面的緣由,可是好久了好久以爲不是這個緣由,由於其餘平臺也是這樣遷移數據的。尚未錯誤。併發

 

 

在本地寫了一個windform測試本地的IIS和測試環境(服務器搭建的虛擬機,有內存和CPU方面的限制)的IIS的網,網站鏈接WCF、wcf鏈接數據庫都沒有問題,而上線到線上卻出問題了,我和運維各類嘗試,後面在想直接寫個winform程序鏈接wcf看看有沒有問題,而後在線上跑確實沒有問題,在想是否是真的網站鏈接wcf鏈接數太多,而後運維直接去寫直接去查詢,原來真的是鏈接數太多,一會兒有兩千多個鏈接數,真的是網站鏈接wcf卡住了,要等要IIS應用程序池默認釋放才行(默認是5分鐘),而winform鏈接wcf,釋放是winform本身釋放的規則,而本地測試環境的IIS會本身釋放的緣由是測試的時候併發太大,而內存和CPU自己很小,形成系統級讓IIS強制回收沒用的鏈接。app

 

查詢某個端口被佔用鏈接數的命令

netstat -ant  |findstr 10209 >1.txt

文件在C:\Users\Administrator下面。

 

IDFA相關的說明:

https://www.zhihu.com/question/38856446

登陸加入知乎

有沒有人給解釋一下IDFA是什麼,能怎麼用?

關注者

 

關注問題寫回答

2 個回答

默認排序

 

沙銘

精通英語和ASO,擅長獲取免費流量,爲國內和出海App提供諮詢服務。

87 人贊同了該回答

瞭解IDFA,看我這篇文章就夠了

雙11剁手後,我靜靜的限制了廣告追蹤

今年雙11爆了,據統計,全天交易額1207億,移動端佔比82%,在馬雲的持續教育和移動端的爆發下,用戶在移動端消費的習慣已經不可逆轉!

然而,另一個你們沒法忽視的問題就是:我的隱私。我在《App推廣實戰(含ASO)》視頻課程中詳細介紹過這個話題,裏面提到了移動用戶的網絡身份證這個概念,有興趣的能夠點擊連接深刻了解。

假如沒有網絡身份證,那麼每一個商家(App)只能基於本身的帳號體系標識用戶,並記錄用戶的行爲。而有了統一的網絡身份證以後,各個商家之間的數據就能夠打通了,天貓不只知道用戶A在淘寶系的購物數據,也能瞭解到該用戶在社交網絡的行爲,以及旅遊的喜愛,等等。

你們能夠想象一下,隨着時間的推移,用戶在移動端的行爲數據越積越多,用戶就會變得愈來愈像透明人,除非換手機,幾乎沒有任何辦法去抵禦這個科技帶來的負面效應。

只有一個例外,蘋果!蘋果的特立獨行體如今諸多方面,用戶隱私就是其中之一。

蘋果爲了保護用戶隱私,早在2012年就再也不容許其生態中的玩家獲取用戶的惟一標識符,可是商家在移動端打廣告的時候又但願能監控到每一次廣告投放的效果,所以,蘋果想出了折中的辦法,就是提供另一套和硬件無關的標識符,用於給商家監測廣告效果,同時用戶能夠在設置裏改變這串字符,致使商家沒有辦法長期跟蹤用戶行爲。這個就叫作廣告標識符(IDFA),設置路徑是「設置->隱私->廣告->還原廣告標識符」,以下圖所示(iOS9)

 

由於這個IDFA不是惟一的,因此一開始行業內是很抵觸的,千方百計去獲取UDID(跟手機綁定的,用戶不能改變),引發蘋果大怒,在13年時禁止全部App獲取UDID,不然不能上架,也正由於其生態的封閉性,才能迫使你們就範。雖然IDFA不是惟一的,可是畢竟賽過沒有,何況也沒有多少用戶會去更改。所以,通過幾番爭鬥,IDFA已經成爲通用的iPhone用戶標識符,這個過程分爲6個階段,我用下圖總結

 

然而在今年iOS10推出後,廣告界大爲震驚,由於蘋果推出了「限制廣告追蹤」功能,設置的路徑和iOS9一致。可能細心的人注意到了,這個功能並不是iOS10獨有啊,在以前的版本中也同樣存在。不過通過實際的測試,在iOS10以前,即便用戶打開這個功能,商家同樣能夠獲取IDFA,只不過與以前的不同了,每次切換這個開關與點擊「還原廣告標識符」的效果同樣。而iOS10就不同了,當用戶打開這個功能後,商家只能獲取到一連串無心義的0,這纔是廣告界大爲震驚的緣由所在!

 

不過,須要澄清的是,限制廣告跟蹤後看到的廣告並不會少,只是商家沒有辦法根據興趣去定向了,由於你成爲了一個沒有身份證的「黑戶」。

據說這個功能一推出,就受到美國用戶的追捧,而亞洲啓用率偏低,據Adjust在10月中旬的一個統計,中國區用戶只有11%打開了這個功能,而各個地區的啓用率也沒有呈現明顯上升的趨勢。

 

不過,不論這個比率如何,移動廣告總會受到一些影響,據國內一知名公司宣稱,在監測廣告的過程當中,IDFA爲0的用戶佔比僅在1%左右。

所以,也許廣告圈對此的反應是有點過頭了,畢竟如今大多數人並不在乎,或者說沒有意識到。若是你們都能善用用戶的信息,僅用於正常的商業推廣,這個問題不會太嚴重。但人性老是貪婪的,人類做爲一個羣體來看,一方面享受着科技的便利,而另外一方面又用科技製造出來更大的問題,等到足夠嚴重的時候再試圖用新的科技來解決,是爲「科技黑洞」!

剁手後,我靜靜的限制了廣告追蹤…

 

 

IDFA 是蘋果 iOS 6 開始新增的廣告標識符,英文全稱是 Identifier for Advertising ,用於給開發者跟蹤廣告效果用的,能夠簡單理解爲 iPhone 的設備臨時身份證,說是臨時身份證是由於它容許用戶更換,IDFA 存儲在用戶 iOS 系統上,同一設備上的應用獲取到的 IDFA 是相同的。iOS 用戶能夠經過(設置程序 -> 通用 -> 還原 -> 還原位置與隱私)更換 IDFA,iOS 10 系統開始提供禁止廣告跟蹤功能,用戶勾選這個功能後,應用程序將沒法讀取到設備的 IDFA。

IDFA 是目前蘋果生態廣告交易的主要標識,通常跟廣告商交易一個用戶後廣告商須要給你提供用戶的 IDFA 做爲憑證,主流的廣告平臺騰訊廣點通、新浪粉絲通對帳是基於 IDFA 的。

 

另外,在統計惟一用戶的時候,IDFA 的可變性會形成部分用戶的重複統計,目前有一些比較好的開源方案,感興趣能夠繼續往下看。

---------------------------------------------------------------------------------

認識一下iOS系統的各類設備識別碼

一、UDID ,全稱是 (Unique Device Identifier),顧名思義,它就是蘋果IOS設備的惟一識別碼,它由40個字符的字母和數字組成,爲了保護用戶隱私蘋果已經禁止讀取這個標識了。

二、UUID,全稱是(Universally Unique IDentifier),是基於iOS設備上面某個單個的應用程序,只要用戶沒有徹底刪除應用程序,則這個 UUID 在用戶使用該應用程序的時候一直保持不變。若是用戶刪除了這個應用程序,而後再從新安裝,那麼這個 UUID 已經發生了改變。UUID 很差的地方就是用戶刪除了你開發的程序之後,基本上你就不可能獲取以前的數據了。

三、MAC 地址,用來定義網絡設備的位置。一個主機會有一個 MAC 地址,MAC 地址是網卡決定的,是固定的,爲了保護用戶隱私蘋果已經禁止讀取這個標識了。

四、OpenUDID,不是蘋果官方的,是一個替代 UDID 的第三發解決方案, 缺點是若是你徹底刪除所有帶有 OpenUDID SDK 包的 App(好比恢復系統等),那麼 OpenUDID 會從新生成,並且和以前的值會不一樣,至關於新設備;

五、IDFA 廣告標示符,適用於對外:例如廣告推廣,換量等跨應用的用戶追蹤等。

六、IDFV,Vindor 標示符 (IDFV-identifierForVendor),來自同一個運營商的應用運行在同一個設備上,此屬性的值是相同的;不一樣的運營商應用運行在同一個設備上值不一樣。

 

關於 openUDID 不能用的說法不正確,至今 openUDID 仍是可用的(iOS7如今沒什麼用戶了),部分廣告渠道的點擊接口依然支持使用 openUDID 做爲用戶標識。

 

 

 

 

 

IDFA流程圖,

網站流程圖,app-webapi-wcf服務-數據庫-消息隊列

 

 

過程當中遇到的錯誤日誌:

 

System.ServiceModel.FaultException`1[System.ServiceModel.ExceptionDetail]: The remote server returned an error: (500) Internal Server Error. (Fault Detail is equal to An ExceptionDetail, likely created by IncludeExceptionDetailInFaults=true, whose value is:

System.Net.WebException: The remote server returned an error: (500) Internal Server Error.

at System.Net.HttpWebRequest.GetResponse()

at HWQ.WCF.CollectService.HttpWebRequestWrapper.GetResponse()

at d.RefshImageCode()

at RefshImageCode(String taskId)

at SyncInvokeRefshImageCode(Object , Object[] , Object[] )

at System.ServiceModel.Dispatcher.SyncMethodInvoker.Invoke(Object instance, Object[] inputs, Object[]& outputs)

at System.ServiceModel.Dispatcher.DispatchOperationRuntime.InvokeBegin(MessageRpc& rpc)

at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage5(MessageRpc& rpc)

at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage41(MessageRpc& rpc)

at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage4(MessageRpc&...).

 

 


System.ServiceModel.FaultException: The server was unable to process the request due to an internal error. For more information about the error, either turn on IncludeExceptionDetailInFaults (either from ServiceBehaviorAttribute or from the <serviceDebug> configuration behavior) on the server in order to send the exception information back to the client, or turn on tracing as per the Microsoft .NET Framework SDK documentation and inspect the server trace logs.

Server stack trace:
at System.ServiceModel.Channels.ServiceChannel.ThrowIfFaultUnderstood(Message reply, MessageFault fault, String action, MessageVersion version, FaultConverter faultConverter)
at System.ServiceModel.Channels.ServiceChannel.HandleReply(ProxyOperationRuntime operation, ProxyRpc& rpc)
at System.ServiceModel.Channels.ServiceChannel.Call(String action, Boolean oneway, ProxyOperationRuntime operation, Object[] ins, Object[] outs, TimeSpan timeout)
at System.ServiceModel.Channels.ServiceChannelProxy.InvokeService(IMethodCallMessage methodCall, ProxyOperationRuntime operation)
at System.ServiceModel.Channels.ServiceChannelProxy.Invoke(IMessage message)

Exception rethrown at [0]:
at System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage reqMsg, IMessage retMsg)
at System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData& msgData, Int32 type)
at HWQ.OtherDataApi.WCFInterface.IWCFAreainfo.GetCityUpdate(DateTime pUpdateTime)
at ***.Call[K](Func`2 callBack)
at **.GetCityUpdate(DateTime pUpdateTime)
at **.city_update(Int64 timestamp)
at lambda_method(Closure , Object , Object[] )
at System.Web.Http.Controllers.ReflectedHttpActionDescriptor.ActionExecutor.<>c__DisplayClass10.<GetExecutor>b__9(Object instance, Object[] methodParameters)
at System.Web.Http.Controllers.ReflectedHttpActionDescriptor.ExecuteAsync(HttpControllerContext controllerContext, IDictionary`2 arguments, CancellationToken cancellationToken)
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
at System.Web.Http.Controllers.ApiControllerActionInvoker.<InvokeActionAsyncCore>d__0.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
at System.Web.Http.Controllers.ActionFilterResult.<ExecuteAsync>d__2.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Web.Http.Filters.AuthorizationFilterAttribute.<ExecuteAuthorizationFilterAsyncCore>d__2.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
at System.Web.Http.Controllers.ExceptionFilterResult.<ExecuteAsync>d__0.MoveNext()

 

 

 


System.ServiceModel.FaultException: The server was unable to process the request due to an internal error. For more information about the error, either turn on IncludeExceptionDetailInFaults (either from ServiceBehaviorAttribute or from the <serviceDebug> configuration behavior) on the server in order to send the exception information back to the client, or turn on tracing as per the Microsoft .NET Framework SDK documentation and inspect the server trace logs.

Server stack trace:
at System.ServiceModel.Channels.ServiceChannel.ThrowIfFaultUnderstood(Message reply, MessageFault fault, String action, MessageVersion version, FaultConverter faultConverter)
at System.ServiceModel.Channels.ServiceChannel.HandleReply(ProxyOperationRuntime operation, ProxyRpc& rpc)
at System.ServiceModel.Channels.ServiceChannel.Call(String action, Boolean oneway, ProxyOperationRuntime operation, Object[] ins, Object[] outs, TimeSpan timeout)
at System.ServiceModel.Channels.ServiceChannelProxy.InvokeService(IMethodCallMessage methodCall, ProxyOperationRuntime operation)
at System.ServiceModel.Channels.ServiceChannelProxy.Invoke(IMessage message)

Exception rethrown at [0]:
at System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage reqMsg, IMessage retMsg)
at System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData& msgData, Int32 type)
at *.GetHomeActivity(Int32 userid, Int32 activityusertype)
at *.Call[K](Func`2 callBack)
at *.gethomeactivityandbanner(String token, Int32 usertype)

 

 

 

 

 

 


System.ServiceModel.FaultException`1[System.ServiceModel.ExceptionDetail]: Unable to connect to any of the specified MySQL hosts. (Fault Detail is equal to An ExceptionDetail, likely created by IncludeExceptionDetailInFaults=true, whose value is:
MySql.Data.MySqlClient.MySqlException: Unable to connect to any of the specified MySQL hosts.
at MBT.Data.SqlHelper.DBUtility.ExecuteScalar(String sql, CommandType cmdtype, DbParameter[] parameters)
at MBT.Data.SqlHelper.DBUtility.ExecuteScalar(String sql, DbParameter[] parameters)
at HWQ.IdfaDataApi.WCFService.ChannelService.GetChannelVerificationID(Int32 ChannelId)
at SyncInvokeGetChannelVerificationID(Object , Object[] , Object[] )
at System.ServiceModel.Dispatcher.SyncMethodInvoker.Invoke(Object instance, Object[] inputs, Object[]& outputs)
at System.ServiceModel.Dispatcher.DispatchOperationRuntime.InvokeBegin(MessageRpc& rpc)
at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage5(MessageRpc& rpc)
at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage41(MessageRpc& rpc)
at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessa...).

 

 

 

System.Threading.Tasks.TaskCanceledException: A task was canceled. at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at System.Web.Http.Controllers.ApiControllerActionInvoker.<InvokeActionAsyncCore>d__0.MoveNext()--- End of stack trace from previous location where exception was thrown --- at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at System.Web.Http.Controllers.ActionFilterResult.<ExecuteAsync>d__2.MoveNext()--- End of stack trace from previous location where exception was thrown --- at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at System.Web.Http.Filters.AuthorizationFilterAttribute.<ExecuteAuthorizationFilterAsyncCore>d__2.MoveNext()--- End of stack trace from previous location where exception was thrown --- at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at System.Web.Http.Controllers.ExceptionFilterResult.<ExecuteAsync>d__0.MoveNext()

相關文章
相關標籤/搜索