原来IDFA(IOS推广获取到用户IOS手机的唯一标识,如果不刷机的话跟安卓的IMEI一样)在公司正常的页面是公用用一个网站和数据库的。
起初怀疑并发数太多,把数据库连接池的数量从一百设置到三百,确实有点反应,但是支持不到一天就又报错。
查看了webapi连接wcf很多都超时,一台api和wcf不够用然后叫运维从一台服务器扩展到多台,报错的频率比原来低了。
看到网上设置是不是因为WCF不是多线程的原因,然后造成等待超时,然后设置了WCF支持多线程,但是还是没有多少作用。
[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerSession, ConcurrencyMode = ConcurrencyMode.Multiple)]
还有怀疑每天的写入调用太频繁,把写入的数据改为消息队列,而不是开线程的插入,不然短时间内线程多开太多,会造成服务器线程异常。
怀疑并发太多造成数据库堵塞(最大一个表的数据达600W)。
经常报错,影响到原有的公司正常业务,但是看了数据一天请求也只不过一二十万的请求量,也不至于这么不抗压,抱着怀疑的心态跟上级申请把这块相关,另外一个原因是其他项目组也要用到这个项目,推广部觉得现在的网站经常报错,也支撑不起另外一个项目的IDFa的访问量,所以考虑独立一个数据库出来,然后在本地IIS和测试环境(一台真实服务器拆分下来分开多台的虚拟服务器)。
然后怀疑是不是跟之前最开始的mysql数据库版本不兼容,造成的原因。因为网上有说这方面的原因,但是很久了很久觉得不是这个原因,因为其他平台也是这样迁移数据的。还没有错误。
在本地写了一个windform测试本地的IIS和测试环境(服务器搭建的虚拟机,有内存和CPU方面的限制)的IIS的网,网站连接WCF、wcf连接数据库都没有问题,而上线到线上却出问题了,我和运维各种尝试,后面在想直接写个winform程序连接wcf看看有没有问题,然后在线上跑确实没有问题,在想是不是真的网站连接wcf连接数太多,然后运维直接去写直接去查询,原来真的是连接数太多,一下子有两千多个连接数,真的是网站连接wcf卡住了,要等要IIS应用程序池默认释放才行(默认是5分钟),而winform连接wcf,释放是winform自己释放的规则,而本地测试环境的IIS会自己释放的原因是测试的时候并发太大,而内存和CPU本身很小,造成系统级让IIS强制回收没用的连接。
查询某个端口被占用连接数的命令
netstat -ant |findstr 10209 >1.txt
文件在C:UsersAdministrator下面。
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系统的各种设备识别码
1、UDID ,全称是 (Unique Device Identifier),顾名思义,它就是苹果IOS设备的唯一识别码,它由40个字符的字母和数字组成,为了保护用户隐私苹果已经禁止读取这个标识了。
2、UUID,全称是(Universally Unique IDentifier),是基于iOS设备上面某个单个的应用程序,只要用户没有完全删除应用程序,则这个 UUID 在用户使用该应用程序的时候一直保持不变。如果用户删除了这个应用程序,然后再重新安装,那么这个 UUID 已经发生了改变。UUID 不好的地方就是用户删除了你开发的程序以后,基本上你就不可能获取之前的数据了。
3、MAC 地址,用来定义网络设备的位置。一个主机会有一个 MAC 地址,MAC 地址是网卡决定的,是固定的,为了保护用户隐私苹果已经禁止读取这个标识了。
4、OpenUDID,不是苹果官方的,是一个替代 UDID 的第三发解决方案, 缺点是如果你完全删除全部带有 OpenUDID SDK 包的 App(比如恢复系统等),那么 OpenUDID 会重新生成,而且和之前的值会不同,相当于新设备;
5、IDFA 广告标示符,适用于对外:例如广告推广,换量等跨应用的用户追踪等。
6、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()