原来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:\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系统的各种设备识别码

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()

关于webapi调用wcf并发假死的分析的更多相关文章

  1. 千万别在UI线程上调用Control.Invoke和Control.BeginInvoke,因为这些是依然阻塞UI线程的,造成界面的假死

    原文地址:https://www.cnblogs.com/wangchuang/archive/2013/02/20/2918858.html .c# Invoke和BeginInvoke 区别 Co ...

  2. WinForm查询大数据界面假死,使用异步调用解决

    用DataGridView无分页绑定一个几千条数据的查询,查询的时候界面直接卡死十几秒,用户体验非常不好,因此用异步操作解决界面卡死的问题原本场景:点击[查询]后,界面直接卡死优化场景:点击[查询]后 ...

  3. winform调用webservice假死怎么解决

    主线程调用外部web service,没有返回时,主线程阻塞了,界面肯定假死耗时操作都是要在工作线程里面执行的.一般情况下winform调用webservice时步骤1添加服务引用---高级----添 ...

  4. 谈.Net委托与线程——解决窗体假死

    转自:http://www.cnblogs.com/smartls/archive/2011/04/08/2008981.html#2457370   引言 在之前的<创建无阻塞的异步调用> ...

  5. curl_multi_select解决curl_multi网页假死问题

    curl_multi可以批处理事务,给网页编程带来很大的方便.不过在使用curl_multi的过程中,我们会遇到一个比较头疼的问题,那就是当并发处理的事务数量过多的时候,就会出现CPU过高,网页假死的 ...

  6. Prism for WPF 搭建一个简单的模块化开发框架(四)异步调用WCF服务、WCF消息头添加安全验证Token

    原文:Prism for WPF 搭建一个简单的模块化开发框架(四)异步调用WCF服务.WCF消息头添加安全验证Token 为什么选择wcf?   因为好像wcf和wpf就是哥俩,,, 为什么选择异步 ...

  7. C# 解决窗体假死的状态

    异步调用是CLR为开发者提供的一种重要的编程手段,它也是构建高性能.可伸缩应用程序的关键.在多核CPU越来越普及的今天,异步编程允许使用非常少的线程执行很多操作.我们通常使用异步完成许多计算型.IO型 ...

  8. C# 委托 线程 窗体假死

    转载:http://www.cnblogs.com/smartls/archive/2011/04/08/2008981.html 异步调用是CLR为开发者提供的一种重要的编程手段,它也是构建高性能. ...

  9. 记一次生产事故的排查与优化——Java服务假死

    一.现象 在服务器上通过curl命令调用一个Java服务的查询接口,半天没有任何响应.关于该服务的基本功能如下: 1.该服务是一个后台刷新指示器的服务,即该服务会将用户需要的指示器数据提前计算好,放入 ...

随机推荐

  1. shell脚本实现MySQL全量备份+异地备份

    一.知识储备工作: Mysql导出数据库语法: mysqldump -u用户名 -p密码 数据库名 > 数据库名.sql shell脚本for循环及if条件判断基本语法 gzip压缩文件用法 r ...

  2. 关闭BottomSheetDialogFragment从后台返回后的动画

    问题 显示BottomSheetDialogFragment后.将当前应用放于后台,切换到其他APP,然后再返回当前应用.此时会看到BottomSheetDialogFragment从下而上的动画再次 ...

  3. spring boot 集成 rabbitmq 指南

    先决条件 rabbitmq server 安装参考 一个添加了 web 依赖的 spring boot 项目 我的版本是 2.5.2 添加 maven 依赖 <dependency> &l ...

  4. scanf("%d",a[i]+j)为什么不加取地址符号

    为什么我画的地方不加取地址符号? 不要在意标题为什么不加分号,因为长度太长了! 二维数组a[3][5]中,a[3]储存的是下一维的地址,a[1]等同于&a[1][0] 同理,a[1]+1等于& ...

  5. 初始 Django

    Python 知识点:函数,面向对象 前端开发:HTML,CSS,JavaScript,jQuery,BootStrap MySQL 数据库 Python 的 WEB 框架 Flask:轻量化,第三方 ...

  6. 121_Power Query之R.Execute的read.xlsx&ODBC

    博客:www.jiaopengzi.com 焦棚子的文章目录 请点击下载附件 一.问题 pq在用 Excel.Workbook 读取一些Excel早期版本(.xls后缀)的文件时候,报错:DataFo ...

  7. Map和WeakMap的方法和区别

    Map Map是一组键值对的结构,具有极快的查找速度. 一.构造函数不同 let map = new Map(); let weakmap = new WeakMap(); 二.内置函数不同 Map的 ...

  8. 浅析kubernetes中client-go Informer

    之前了解了client-go中的架构设计,也就是 tools/cache 下面的一些概念,那么下面将对informer进行分析 Controller 在client-go informer架构中存在一 ...

  9. Three.js 打造缤纷夏日3D梦中情岛 🌊

    声明:本文涉及图文和模型素材仅用于个人学习.研究和欣赏,请勿二次修改.非法传播.转载.出版.商用.及进行其他获利行为. 背景 深居内陆的人们,大概每个人都有过大海之梦吧.夏日傍晚在沙滩漫步奔跑:或是在 ...

  10. 《Mybatis 手撸专栏》第10章:使用策略模式,调用参数处理器

    作者:小傅哥 博客:https://bugstack.cn 沉淀.分享.成长,让自己和他人都能有所收获! 一.前言 你这代码写的,咋这么轴呢! 说到轴,让我想起初中上学时老师说的话:"你那脑 ...