java,如何把session保存到数据库里面???
aspnet中,session默认以inproc模式存储,也就是保存在iis进程中,这样有个优点就是效率高,但不利于为本负载均衡扩展。可以把session信息保存在SQL Server中,据说,该种方式比起inproc性能损失为10%-20%。如何实现呢,主要分两步介绍:
1、初始化SQL Server中的状态数据库
ASPNET SQL Server 提供注册工具Aspnet_regsqlexe,用于创建供 ASPNET 中的 SQL Server 提供程序使用的 Microsoft SQL Server 数据库。Aspnet_regsqlexe位于 /%windir%/MicrosoftNET/Framework/<versionNumber>/aspnet_regsqlexe 目录下。如果麻烦,可以 直接用visual studio tools 的命令提示工具中直接输入aspnet_regsqlexe使用。用法如下:
Aspnet_regsqlexe <options>
可以用如下的语法来添加默认session数据库ASPState
aspnet_regsqlexe -S localhost -U sa -P why1234 -ssadd -sstype p
-S,-U/-P
必须是大写,分别表示数据库服务器,用户名和密码。
-ssadd / –ssremove 参数:
-ssadd表示是添加Session数据库, -ssremove表示移除Session数据库
创建自定义数据库myAppState,可以用如下的语法:
aspnet_regsqlexe -S localhost -U sa -P why1234 -ssadd -sstype c -d myAppState
2、配置webconfig
在webconfig的 <systemweb>节下添加如下配置:
<sessionState mode="SQLServer" sqlConnectionString="server=localhost; uid=sa; pwd=123456;"/>
如果在初始化数据库的时候,创建了自定义数据库可以用类似于如下的的配置:
<sessionState mode="SQLServer" allowCustomSqlDatabase="true" sqlConnectionString="server=localhost; DataBase=myAspState;uid=sa; pwd=123456;"/>
通过以上两步的设置,已经可以了。详细情况请参阅msdn。
aspnet中,session默认以inproc模式存储,也就是保存在iis进程中,这样有个优点就是效率高,但不利于为本负载均衡扩展。可以把session信息保存在SQL Server中,据说,该种方式比起inproc性能损失为10%-20%。如何实现呢,主要分两步介绍:
1、初始化SQL Server中的状态数据库
ASPNET SQL Server 提供注册工具Aspnet_regsqlexe,用于创建供 ASPNET 中的 SQL Server 提供程序使用的 Microsoft SQL Server 数据库。Aspnet_regsqlexe位于 /%windir%/MicrosoftNET/Framework/<versionNumber>/aspnet_regsqlexe 目录下。如果麻烦,可以 直接用visual studio tools 的命令提示工具中直接输入aspnet_regsqlexe使用。用法如下:
Aspnet_regsqlexe <options>
可以用如下的语法来添加默认session数据库ASPState
aspnet_regsqlexe -S localhost -U sa -P why1234 -ssadd -sstype p
-S,-U/-P
必须是大写,分别表示数据库服务器,用户名和密码。
-ssadd / –ssremove 参数:
-ssadd表示是添加Session数据库, -ssremove表示移除Session数据库
创建自定义数据库myAppState,可以用如下的语法:
aspnet_regsqlexe -S localhost -U sa -P why1234 -ssadd -sstype c -d myAppState
2、配置webconfig
在webconfig的 <systemweb>节下添加如下配置:
<sessionState mode="SQLServer" sqlConnectionString="server=localhost; uid=sa; pwd=123456;"/>
如果在初始化数据库的时候,创建了自定义数据库可以用类似于如下的的配置:
<sessionState mode="SQLServer" allowCustomSqlDatabase="true" sqlConnectionString="server=localhost; DataBase=myAspState;uid=sa; pwd=123456;"/>
通过以上两步的设置,已经可以了。详细情况请参阅msdn。
工作中遇到一个 docker 容器下 UDP 协议网络不通的问题,困扰了很久,也比较有意思,所以想写下来和大家分享。
我们有个应用是基于 UDP 协议的,部署上去发现无法工作,但是换成 TCP 协议是可以的(应用同时支持 UDP、TCP 协议,切换成 TCP 模式发现一切正常)。
虽然换成 TCP 能解决问题,但是我们还是想知道到底 UDP 协议在容器网络模式下为什么会出现这个问题,以防止后面其他 UDP 应用会有异常。
这个问题抽象出来是这样的:如果有 UDP 服务运行在宿主机上(或者运行在网络模型为 host 的容器里),并且监听在 0000 地址(也就是所有的 ip 地址),从运行在 docker bridge(网桥为 docker0) 网络的容器运行客户端访问服务,两者通信有问题。
注意以上的的限制条件,通过测试,我们发现下来几种情况都是正常的:
这个问题在 docker 上也有 issue 记录,但是目前并没有合理的解决方案。
https://githubcom/moby/moby/issues/15127
https://githubcom/iotaledger/iri/issues/961
这篇文章就分析一下出现这个问题的原因,希望给同样遇到这个问题的读者提供些帮助。
这个问题很容易重现,我的实验是在 ubuntu1604 下用 netcat 命令完成的,其他系统应该类似。
在宿主机上通过 nc 监听 56789 端口,然后使用 bridge 网络模式,run 一个容器,在容器里面使用 nc 发数据。
第一个报文是能发送出去的,但是以后的报文虽然在网络上能看到,但是对方无法接收。
在宿主机运行 nc UDP 服务器(-u 表示 UDP 协议,-l 表示监听的端口)
注:默认没有指定绑定ip,就是监听在0000上。
然后在同一宿主机上,启动一个容器,运行客户端:
nc 的通信是双方的,不管对方输入什么字符,回车后对方就能立即收到。
但是在这个模式下,客户端第一次输入对方能够收到,后续的报文对方都收不到。
在这个实验中,容器使用的是 docker 的默认网络,容器的 ip 是 1721703,通过 veth pair(图中没有显示)连接到虚拟网桥 docker0(ip 地址为 1721701),宿主机本身的网络为 eth0,其 ip 地址为 172161313。
遇到这种疑难杂症,第一个想到的抓包。
我们需要在 docker0 上抓包,因为这是报文必经过的地方。
通过过滤容器的 ip 地址,很容器找到感兴趣的报文:
为了模拟多数应用一问一答的通信方式,我们一共发送三个报文,并用 tcpdump 抓取 docker0 接口上的报文:
抓包的结果如下,可以发现第一个报文发送出去没有任何问题。
UDP 是没有 ACK 报文的,所以客户端无法知道对方有没有收到,这里说的没有问题没有看到对应的 ICMP 差错报文。
但是第二个报文从服务端发送的报文,对方会返回一个 ICMP 告诉端口 38908 不可达;第三个报文从客户端发送的报文也是如此。以后的报文情况类似,双方再也无法进行通信了。
而此时主机上 UDP nc 服务器并没有退出,使用 ss -uan | grep 56789 可能看到它仍然在监听着该端口。
从网络报文的分析中可以看到服务端返回的报文源地址不是我们预想的 eth0 地址,而是 docker0 的地址,而客户端直接认为该报文是非法的,返回了 ICMP 的报文给对方。
那么问题的原因也可以分为两个部分:
第一个问题的关键词是:UDP 和多网络接口。
因为如果主机上只有一个网络接口,发出去的报文源地址一定不会有错;而我们也测试过 TCP 协议是能够处理这个问题的。
通过搜索,发现这确实是个已知的问题。
这个问题可以归结为一句话:UDP 在多网卡的情况下,可能会发生服务器端源地址不对的情况,这是内核选路的结果。
为什么 UDP 和 TCP 有不同的选路逻辑呢?
因为 UDP 是无状态的协议,内核不会保存连接双方的信息,因此每次发送的报文都认为是独立的,socket 层每次发送报文默认情况不会指明要使用的源地址,只是说明对方地址。
因此,内核会为要发出去的报文选择一个 ip,这通常都是报文路由要经过的设备 ip 地址。
那么,为什么 dnsmasq 服务没有这个问题呢?
于是我使用 strace 工具抓取了 dnsmasq 和出问题应用的网络 socket 系统调用,来查看它们两个到底有什么区别。
dnsmasq 在启动阶段监听了 UDP 和 TCP 的 54 端口
因为是在本地机器上测试的,为了防止和本地 DNS 监听的DNS端口冲突,我选择了 54 而不是标准的 53 端口:
比起 TCP,UDP 部分少了 listen,但是多个 setsockopt(4, SOL_IP, IP_PKTINFO, [1], 4) 这句。
到底这两点和我们的问题是否有关,先暂时放着,继续看传输报文的部分。
dnsmasq 收包和发包的系统调用,直接使用 recvmsg 和 sendmsg 系统调用:
而出问题的 UDP 应用 strace 结果如下:
其对应的逻辑是这样的:使用 ipv6 绑定在 0000 和 6088 端口,调用 getsockname 获取当前 socket 绑定的端口信息,数据传输过程使用的是 recvfrom 和 sendto。
对比下来,两者的不同有几点:
因为是在传输数据的时候出错的,因此第一个疑点是 sendmsg 和 sendto 的某些区别导致选择源地址有不同,通过 man sendto 可以知道 sendmsg 包含了更多的控制信息在 msghdr。
一个合理的猜测是 msghdr 中包含了内核选择源地址的信息!
通过查找,发现 IP_PKTINFO 这个选项就是让内核在 socket 中保存 IP 报文的信息,当然也包括了报文的源地址和目的地址。 IP_PKTINFO 和 msghdr 的关系可以在这个 stackoverflow 中找到:
https://stackoverflowcom/questions/3062205/setting-the-source-ip-for-a-udp-socket
而 man 7 ip 文档中也说明了 IP_PKTINFO 是怎么控制源地址选择的:
如果 ipi_spec_dst 和 ipi_ifindex 不为空,它们都能作为源地址选择的依据,而不是让内核通过路由决定。
也就是说,通过设置 IP_PKTINFO socket 选项为 1,然后使用 recvmsg 和 sendmsg 传输数据就能保证源地址选择符合我们的期望。
这也是 dnsmasq 使用的方案,而出问题的应用是因为使用了默认的 recvfrom 和 sendto。
为什么内核会把源地址和之前不同的报文丢弃,认为它是非法的?
因为我们前面已经说过,UDP 协议是无连接的,默认情况下 socket 也不会保存双方连接的信息。即使服务端发送报文的源地址有误,只要对方能正常接收并处理,也不会导致网络不通。
但是 conntrack 不是这样,内核的 netfilter 模块会保存连接的状态,并作为防火墙设置的依据。
它保存的 UDP 连接,只是简单记录了主机上本地 ip 和端口,和对端 ip 和端口,并不会保存更多的内容。
关于 这块可参考 intables info 网站的文章:
http://wwwiptablesinfo/en/connection-statehtml#UDPCONNECTIONS
在找到根源之前,我们曾经尝试过用 SNAT 来修改服务端应答报文的源地址,期望能够修复该问题,但是却发现这种方法行不通,为什么呢?
因为 SNAT 是在 netfilter 最后做的,在之前 netfilter 的 conntrack 因为不认识该 connection,直接丢弃了,所以即使添加了 SNAT 也是无法工作的。
那能不能把 conntrack 功能去掉呢?比如解决方案:
答案也是否定的,因为 NAT 需要 conntrack 来做翻译工作,如果去掉 conntrack 等于 SNAT 完全没用。
知道了问题的原因,解决方案也就很容易找到。
nc 可以跟两个参数,分别代表 ip 和 端口,表示服务端监听在某个特定 ip 上。
如果接收到的报文目的地址不是 172161313,也会被内核直接丢弃,这种情况下,服务端和客户端也能正常通信。
docker 容器网络下 UDP 协议的一个问题
https://cizixscom/2017/08/21/docker-udp-issue/
Setting the source IP for a UDP socket
https://stackoverflowcom/questions/3062205/setting-the-source-ip-for-a-udp-socket
LinuxC下获取UDP包中的路由目的IP地址和头标识目的地址
https://wwwcnblogscom/kissazi2/p/3158603html
Source IP address selection
https://wwwibmcom/docs/en/zos/210topic=profiletcpip-source-ip-address-selection
UDP recvmsg 返回目的地址和目的接口信息
http://blogchinaunixnet/uid-16813896-id-4593514html
告知你不为人知的 UDP:连接性和负载均衡
https://cloudtencentcom/developer/article/1004554
告知你不为人知的 UDP:疑难杂症和使用
https://cloudtencentcom/developer/article/1004554
人事档案分为在职、离职、退休、后备四个人员库。系统内置丰富的人事档案字段。用户可自行定义人事档案的数据字段,可自行设计人事档案界面。
人事档案中包括薪酬记录、考勤记录、绩效记录、培训记录、社保记录、调岗记录、调薪记录、奖惩记录等常用数据子集。用户也可自行增加新的数据子集。可以针对子集进行独立的导入、导出、统计分析。
系统支持人事业务的在线办理,包括:入职、转正、调岗、调薪、奖励、处分、离职、复职等。这些业务即可以直接办理,也可以通过系统工作流平台进行审批处理。业务办理的结果直接记录在人事档案中。
人事档案数据支持分部门管理。各分公司或部门可以独立管理本部人员。
可以使用人事档案的所有字段(包括自定义字段)组合查询。查询条件可以保存为查询模板。快捷查询与组合查询可以联合使用。
人事档案数据支持Excel格式的导入与导出。用户可对人事档案进行批量编辑。
系统内置丰富的人事报表、图表,包括:人员构成情况分类统计表、员工明细花名册、部门员工花名册、各部门职务统计表、 员工入职离职统计表、各部门员工生日报表、各部门及岗位编制人数统计表。 用户可自定义二维统计报表,也可使用系统报表平台,自行设计个性化的人事报表。
支持自动快速识别、读入员工身份证信息,杜绝伪造身份证,提高员工个人档案信息准确度,减少信息录入工作量。(实现此功能需要配备硬件设备身份证识别器)。 部门管理。用户可以对部门进行设立和撤销操作,建立无限层级的树形部门结构。可以回顾部门结构的历史记录。可以即时查看组织机构图,并直接打印,也可以导出为HTML格式。
职务及岗位管理。用户可以对职务和岗位进行设计和撤销。对岗位编制进行管理。可以为职务及岗位建立说明书。可以实时统计通过各部门及岗位编制人数统计表,可以随时了解企业编制情况。
用户可以建立精确的岗位及员工能力素质模型。为人力资源各项工作提供量化依据。能力素质模块使用系统指标库来构建。 客户可以对员工的劳动合同、培训合同、保密协议进行新签、续签等操作。 提供劳动合同期满提醒、未签劳动合同人员提醒、合同续签提醒。
合同报表功能可以随时展现各类合同的明细数据。
合同数据支持分部门管理,各分公司或部门可以独立管理本部的合同。 用户可以自定义薪酬帐套。通过计算公式、等级表等方式,实现岗位工资、级别工资、工龄工资、学历津贴、考勤扣款、社保扣款、绩效奖、个人所得税等各类常见的工资项目。
可实现一月多次发放工资,支持多次工资合并计税。
支持年终奖的十二个月分摊计税。
薪酬数据支持分部门管理,各分公司或部门可以独立管理本部的薪酬。
薪酬数据支持在线批量编辑。
薪酬发放支持标准的工作流审批。
员工可以在线进行薪酬申诉。
每月薪酬数据自动记录在人事档案中。
系统内置薪酬报表,包括:各部门员工薪酬明细表、各部门及岗位薪酬汇总表、部门月工资条打印表、职务薪酬汇总表、部门及岗位薪酬多月合计表、 部门及岗位多月薪酬对比表、员工薪酬多月合计表。 用户可以自定义各类保险福利类别。
用户可为员工批量创建保险帐户,支持为当月入职员工开户,离职员工退保。
社保缴费自动核算。
可以工资计算中自动引入社保缴费数据。
社保报表。 系统支持定性及定量两种绩效考核方式,如:360度考核、量化考核等考核方式。
系统内置各岗位常用的绩效考核表,可供用户直接使用。用户也可以自行设定考核指标、评分权重、计分公式等项目,创建自己的考核表。
考核任务发布后,员工直接在线进行绩效打分,自动完成分数汇总计算。考核结果自动记录在员工档案中。
薪酬模块可以自动引用绩效考核结果,直接计算用户的绩效工资。
员工可以在线进行考核申诉与反馈。
系统内置绩效报表,包括:绩效考核结果一览表、绩效考核记录一览表、考核结果单指标分析表、考核评分记录明细表、各部门量化指标分析表、部门考核等级汇总表。
绩效数据支持分部门管理,各分公司或部门可以独立管理本部的绩效。 与企业现有考勤机结合,实现班次定义、员工排班、智能抓班、考勤汇总计算等功能。
系统支持请假、出差、加班、补休、调班、停工等考勤业务管理。
薪酬模块可以直接引用月考勤结果进行相关计算。
假期管理中可以自定义法定假期与企业假期。
考勤数据支持分部门管理,各分公司或部门可以独立管理本部的考勤。
系统提供常用的一组考勤数据报表。 培训管理员可以向员工进行培训需求调查。
各部门上报培训需求,汇总成培训计划,计划内容包括培训的时间、地点、参与人、预算等。培训计划可以在线申报。
由培训计划生成培训的实施方案,详细记录培训实施情况。
培训评价管理,记录员工在每次培训中的评价。
培训记录自动记入员工档案。
培训资源管理。可以管理培训课程、培训机构、培训讲师、培训资料、培训地点等。
培训数据支持分部门管理,各分公司或部门可以独立管理本部的培训。
系统内置培训报表,包括:各部门培训计划费用统计表、各部门培训计划人数统计表、各部门培训实施费用统计表、各部门培训实施人数统计表、各部门实施费用明细表等。 用户可以制订招聘计划,包括招聘的岗位、要求、人数,招聘流程定义等。招聘计划可在线申报。
应聘简历可以详细记录应聘者资料,并记录他们在应聘各阶段的评价。
应聘流程通过系统工作流平台完成,可以管理求职者的整个应聘过程。
系统内置招聘报表,包括:各部门招聘计划明细表、各部门招聘岗位应聘情况明细表、应聘人员构成情况分类统计表、招聘计划各阶段人数统计表、各岗位招聘及应聘人数统计表。 企业可在互联网上对外发布招聘网站,通过网站实时发布各类招聘职位。
应聘者可以在招聘网站上直接应聘,在线填写简历等信息。
招聘管理员可在系统后台直接查阅、筛选、统计应聘人员信息。
招聘全过程管理,可以记录应聘者在各阶段面试、笔试中的成绩、评价。
通过筛选的应聘人员,可以直接入岗,转为在职人员,或进入企业后备人员库。
提供各岗位应聘人员汇总表等报表。 劳动合同期满提醒
员工生日提醒
未签劳动合同人员提醒
合同续签提醒
员工转正提醒 系统日志管理。
在线用户查看。
业务监控台。查看系统中所有工作流业务的运行状态。
部门数据权限管理。
栏目访问权限管理。
用户及角色管理。
标准代码库。
数据结构管理
缓存管理 1、稳定支持 2 00 个以上的并发用户;
2、关键业务在 200 用户并发下的快速响应;
3、系统有完善的缓存管理工具,以针对各种压力场景进行配置调优。 1、设计安全的物理网络和网络架构
2、允许从 Internet 访问,并设计有相关安全措施
3、使用安全的授权方式
4、最终用户和 WEB 服务器间使用安全的通信协议,账号、密码等关键数据需进行加密传输
5、Web 服务器同数据库间使用安全的通信协议
6、数据采用安全的保护措施、设计安全的备份和恢复策略
7、提供数据应急方案
8、如果客户端需要下载控件,则必须支持数字签名,不能降低IE的缺省安全设置。 1、模块化、组件式开发模式,系统采用“平台框架+功能模块+客户化配置”
的设计思想,提供便于进行二次开发的各种接口,无需对系统的底层基础进行修改,就能够根据需要,随时进行单个功能模块的修改、添加和升级;
2、系统应具有良好的扩展性与二次开发能力。客户方系统管理员使用系统提供
的工具即可以对功能进行更新和扩展。第三方开发人员可以在本系统基础上进行代码开发,厂商可提供相应的培训和技术支持;
3、内置国际标准的工作流引擎和常用的工作流程,可自定义个性化的工作流程,满足对一项工作进行不同人员的多级审核需求,在每个审批步骤完成后可以自动修改相关的业务数据,可自动判断也可人工选择流程分支走向;
4、整个系统应基于标准Portal技术搭建,具有动态部署及系统集成能力。
5、有统一的权限控制机制,对系统中的所有资源都要能进行权限控制。权限可集中控制,也可深入到各模块中进行控制。权限可直接授予门户用户、员工、岗位、机构、用户组、用户类别、特殊身份组等和用户关联对象上;
6、带报表开发工具,用户可用它自行定义各类明细、统计报表,并快速呈现出各种复杂数据间的关系。
7、支持云计算平台。 1、完备的应用的可用性措施;
2、完备的数据库的可用性解决方案;
3、应用系统和数据库系统支持负载均衡集群(cluster)。 1、与其他应用统一认证、统一授权(SS0);
2、与其他应用进行数据交互并遵从 XML 标准;
3、与流行办公软件集成。 1、数据库服务器和应用服务器支持Windows Server系统操作系统,软件系统基于微软net平台开发。
2、数据库管理系统采用SqlServer2000或2005;
3、支持 IE 60 及以上版本的浏览器,纯 B/S 系统架构模式
0条评论