《 Windows下搭建Tomcat集群基础入门详解 》

前言
在搭建 《 Apache + Tomcat 实现Web服务器集群 》 前我们还需要实现 Tomcat集群实现Session复制 ,这样用户只需要登录一次即可,就不用每次请求都需要登录了,这儿使用的是两个 Tomcat 节点实现集群及节点间 Session 的复制。

首先我们需要找到 Tomcat 的配置文件 “ server.xml  ” ,在其中找到 <Engine> 节点,在该节点下添加一个 <Cluster className =“org.apache.catalina.ha.tcp.SimpleTcpCluster”/> 节点,

关于 Tomcat 集群的默认配置如下:

<!--  Cluster-(集群) 节点,在配置 Tomcat 集群时,必须添加此节点用以启动 集群 -->
<Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster" channelSendOptions="8"><!--  Manager-节点决定如何管理集群的 Session 信息 --><Manager className="org.apache.catalina.ha.session.DeltaManager"expireSessionsOnShutdown="false"notifyListenersOnReplication="true"/><!--  Channel-是 Tomcat 节点之间进行通讯的工具 --><!--  Channel 共包括5个组件:Membership、Receiver、Sender、Transport、Interceptor --><Channel className="org.apache.catalina.tribes.group.GroupChannel"><!--  Membership-用于维护集群中可用的节点列表 --><Membership className="org.apache.catalina.tribes.membership.McastService"address="228.0.0.4"port="45564"frequency="500"dropTime="3000"/><!--  Receiver-接收器,负责接收消息 --><!--  两种接收器: BioReceiver(阻塞式)、NioReceiver(非阻塞式) --><Receiver className="org.apache.catalina.tribes.transport.nio.NioReceiver"address="auto"port="4000"autoBind="100"selectorTimeout="5000"maxThreads="6"/><!--  Sender-发送器,使用 Sender 中内嵌的 Transport 组件实现消息的返送 --><Sender className="org.apache.catalina.tribes.transport.ReplicationTransmitter"><!--  消息发送也分为两种:bio.PooledMultiSender(阻塞式)、nio.PooledParallelSender(非阻塞式)  --><Transport className="org.apache.catalina.tribes.transport.nio.PooledParallelSender"/></Sender><!--  Interceptor-Cluster的拦截器,当拦截到某个节点的关闭信息时,自身节点会通过 TCP 方式连接到此(异常节点)节点,确保此节点真正关闭,从而更新集群的中可用节点列表--><Interceptor className="org.apache.catalina.tribes.group.interceptors.TcpFailureDetector"/><!--  Interceptor-Cluster的拦截器,MessageDispatch15Interceptor 会先将等待发送的消息进行排队,然后将排好队的消息转给 Sender ,再由 Sender 进行消息的发送 --><Interceptor className="org.apache.catalina.tribes.group.interceptors.MessageDispatch15Interceptor"/></Channel><!--  ReplicationValve-在处理请求前后打日志 --><Valve className="org.apache.catalina.ha.tcp.ReplicationValve" filter=""/><!--  JvmRouteBinderValve-当 Apache 的 mod_jk 发生错误时,确保同一客户端的请求发送到集群的同一个节点 --><Valve className="org.apache.catalina.ha.session.JvmRouteBinderValve"/><!--  Deployer-确保所有 Tomcat 集群中所有节点的一致性 --><Deployer className="org.apache.catalina.ha.deploy.FarmWarDeployer"tempDir="/tmp/war-temp/"deployDir="/tmp/war-deploy/"watchDir="/tmp/war-listen/"watchEnabled="false"/><!--  ClusterListener-监听器,监听 Cluster 组件接收的消息,如果在集群中配置了 DeltaManager ,则 ClusterSessionListener 会将拦截到的消息床底给 DeltaManager --><ClusterListener className="org.apache.catalina.ha.session.ClusterSessionListener"/>
</Cluster>

配置简述:
1、组播地址为 228.0.0.4 。
2、组播端口为 45564(端口和地址共同决定了集群成员 status)。
3、广播的 IP 是 java.net.InetAddress.getLocalHost().getHostAddress()(请确保没有广播127.0.0.1,这是一个常见错误,如果广播为 127.0.0.1,集群会创建失败哟!)。
4、该 TCP 端口监听复制消息是在第一个可用的 socket 服务器 4000-4100 范围中。
5、两个侦听配置 ClusterSessionListener 和 JvmRouteSessionIDBinderListener ,在这儿我只使用了 ClusterSessionListener 即可。
6、两个拦截器配置为 TcpFailureDetector 和 MessageDispatch15Interceptor。

注意事项:
使用上述配置将使用 DeltaManager 复制 DeltaSession 来启用 Tomcat 节点间全部会话的复制。也就是将会话复制到集群中的所有其他 Tomcat 节点。
关于这个 Tomcat 集群配置只使用于较小的群集非常适用,但我们不建议将它用于较大的群集(多个 Tomcat 节点)。
另外,在使用 DeltaManager 时,它将复制到所有节点,只要在集群的 Tomcat 节点中配置了集群即使没有部署应用程序的节点也是复制/广播到该节点。
为了解决这个问题,需要使用备份管理器。此管理器仅将会话数据复制到一个备份节点,并且仅复制到已部署应用程序的节点。使用备份管理器的缺点:和 DeltaManager 的测试不一样。

实现 Tomcat 集群需要满足基本要求
1、所有的会话属性都必须实现 java.io.Serializable 接口。
2、取消 server.xml中 Cluster 元素注释。
3、如果在集群中自定了 Valve,则请确保该在 server.xml 中定义了 ReplicationValve 元素。
4、如果一个集群中所有的 Tomcat 实例在同一台服务器上运行,​​请确保 server.xml 中 TcpListenPort 属性对于每个实例都是唯一的,但是在大多数情况下,Tomcat 可通过自动检测 4000-4100 范围内的可用端口来解决此问题。
5、必须确保在应用程序 web.xml 配置文件中存在 <distributable/> 元素。
6、如果您使用的是 mod_jk 连接器,请确保在引擎中设置了 jvmRoute 属性 ( <Engine name="Catalina" jvmRoute="node01" > ),并且 jvmRoute 属性值与 workers.properties 中所配置 workers 的名称相同。
7、确保所有节点具有相同的时间(如果时间不一致,这儿有个代名词叫时间戳问题)并与NTP服务同步。
8、确保您的负载均衡器配置为具有粘性的会话模式。

在 Tomcat 中启用会话复制,三种方法实现会话相同
1、使用会话持久性,并将会话保存到共享文件系统(PersistenceManager + FileStore)
2、使用会话持久性,并将会话保存到共享数据库(PersistenceManager + JDBCStore)
3、使用内存复制,使用 Tomcat 附带的 SimpleTcpCluster(lib / catalina-tribes.jar + lib / catalina-ha.jar)

集群描述
Membership 是使用组播心跳建立的。因此,如果希望细分 Tomcat 群集,可以通过修改 <Membership> 元素中的多播IP地址或端口来实现。
心跳包含 Tomcat节点的IP地址和 Tomcat 监听复制流量的 TCP 端口。所有数据通信都通过 TCP 进行的。
ReplicationValve 主要被用来找出当请求已经完成并开始复制的会话,如果有,则只有在会话发生改变时才会复制 session 数据(主要通过在会话上调用 setAttribute 或 removeAttribute 实现)。
关于 Tomcat 中 session 数据复制分为同步复制和异步复制,这个会直接影响集群性能。
在同步复制模式下,请求不会返回,直到复制的会话通过线路发送并重新实例化所有其他群集节点。
同步与异步配置使用该 channelSendOptions 标志并且是一个整数值。SimpleTcpCluster/DeltaManager 组合的默认值是 “ 8 ”,这个是异步的。
为了更加方便,channelSendOptions 还可以通过别名来设置,然后在启动时将其转换为整数值。
别名包括:“异步”(别名为“async”),“byte_message”(别名为“字节”),“多播”,“安全”,“synchronized_ack”(别名为“同步”),“udp” ”。
使用逗号分隔多个名称,例如通过选项的“异步,多播” SEND_OPTIONS_ASYNCHRONOUS | SEND_OPTIONS_MULTICAST。

将崩溃后的会话绑定到故障转移节点
如果在集群中使用的是 mod_jk 而不是使用 “ 粘性会话 ”,或者由于某些原因,粘性会话不起作用,或者您只是简单地进行故障转移,则需要修改会话标识即可,因为它之前包含上一个 Tomcat 的  worker  标识(由 jvmRoute 在 <Engine/> 元素中定义)。
为了解决故障转移的问题,需要使用 JvmRouteBinderValve。

使用 JvmRouteBinderValve 重会话 ID 以确保在故障切换后下一个请求将保持粘滞状态(并且不会退回到随机节点,因为该 worker 不再可用)。Valve 重写同名的 cookie 中的 JSESSIONID 值。如果没有这个 Valve,在 mod_jk 模块发生故障时将难以确保粘性。

注意:
需要注意的是如果要在 server.xml 中添加自己的 Valve,那么缺省的值不再有效,请确保添加默认定义的所有适当的 Valve。

提示:
通过属性 sessionIdAttribute,可以更改包含旧会话标识的请求属性名称。
默认属性名称是 org.apache.catalina.ha.session.JvmRouteOrignalSessionID。

技巧:
在将节点终止时,您可以通过 JMX 启用 mod_jk 转换模式!在所有 JvmRouteBinderValve 备份上设置为 true,在 mod_jk 上禁用 worker,然后终止该节点并重新启动它!然后启用 mod_jk Worker 并再次禁用 JvmRouteBinderValves。这个用例意味着只有被请求的会话被迁移。

配置实例

<Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster"channelSendOptions="6"><Manager className="org.apache.catalina.ha.session.BackupManager"expireSessionsOnShutdown="false"notifyListenersOnReplication="true"mapSendOptions="6"/><!--<Manager className="org.apache.catalina.ha.session.DeltaManager"expireSessionsOnShutdown="false"notifyListenersOnReplication="true"/>--><Channel className="org.apache.catalina.tribes.group.GroupChannel"><Membership className="org.apache.catalina.tribes.membership.McastService"address="228.0.0.4"port="45564"frequency="500"dropTime="3000"/><Receiver className="org.apache.catalina.tribes.transport.nio.NioReceiver"address="auto"port="5000"selectorTimeout="100"maxThreads="6"/><Sender className="org.apache.catalina.tribes.transport.ReplicationTransmitter"><Transport className="org.apache.catalina.tribes.transport.nio.PooledParallelSender"/></Sender><Interceptor className="org.apache.catalina.tribes.group.interceptors.TcpFailureDetector"/><Interceptor className="org.apache.catalina.tribes.group.interceptors.MessageDispatchInterceptor"/><Interceptor className="org.apache.catalina.tribes.group.interceptors.ThroughputInterceptor"/></Channel><Valve className="org.apache.catalina.ha.tcp.ReplicationValve"filter=".*\.gif|.*\.js|.*\.jpeg|.*\.jpg|.*\.png|.*\.htm|.*\.html|.*\.css|.*\.txt"/><Deployer className="org.apache.catalina.ha.deploy.FarmWarDeployer"tempDir="/tmp/war-temp/"deployDir="/tmp/war-deploy/"watchDir="/tmp/war-listen/"watchEnabled="false"/><ClusterListener className="org.apache.catalina.ha.session.ClusterSessionListener"/>
</Cluster>

将其进行分解:

主元素:

<Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster"channelSendOptions="6">

在这个元素中所有的集群细节都可以配置。其中 channelSendOptions 是连接到 SimpleTcpCluster 类或调用 SimpleTcpCluster 的任何对象所发送的每个消息的标志。
在 java 文档中可以查看到发送标志的具体描述,DeltaManager 使用 SimpleTcpCluster 发送信息。而备份管理器则直接通过通道发送消息。

管理器配置模板:

<Manager className="org.apache.catalina.ha.session.BackupManager"expireSessionsOnShutdown="false"notifyListenersOnReplication="true"mapSendOptions="6"/>
<!--
<Manager className="org.apache.catalina.ha.session.DeltaManager"expireSessionsOnShutdown="false"notifyListenersOnReplication="true"/>
-->

如果 <Context/> 元素中没有定义管理器,将使用该管理器模板。在 Tomcat 5.x 中,每个 webapp 的标记分布必须使用相同的管理器,因为在 Tomcat 中可以为每个 webapp 定义一个管理器类,
所以可以在一个集群中使用混合管理器。很显然,一个节点上的应用程序的管理器与另一个节点上的同一个应用程序的的管理器相对应。
如果没有为 webapp 指定管理器,并且 webapp 被标记为 <distributable /> Tomcat将采用此管理器配置并创建克隆此配置的管理器实例。

通信:

<Channel className="org.apache.catalina.tribes.group.GroupChannel">

在 Tomcat 中使用的组通信框架。该元素封装了与通信和成员逻辑相关的所有内容。

节点间的组播:

<Membership className="org.apache.catalina.tribes.membership.McastService"address="228.0.0.4"port="45564"frequency="500"dropTime="3000"/>

集群中节点通过多播的方式完成的。在节点中还支持静态成员使用 StaticMembershipInterceptor,如果想延长加入的节点超出多播,
那么必须地址属性是使用的组播地址,端口是组播端口。这两者一起创建集群分离。如果想要保证群集和生产群集的高性能,最简单的配置是使群集位于与生产群集不同的多播地址/端口组合之上。
成员组通过广播其自身的 TCP地址/端口 到其他节点,以便节点之间的通信可以通过TCP完成。

消息接收:

<Receiver className="org.apache.catalina.tribes.transport.nio.NioReceiver"address="auto"port="5000"selectorTimeout="100"maxThreads="6"/>

在一个节点中,发送和接收数据的逻辑已被分解为两个功能组件。
该 Receiver 顾名思义就是负责接消息的接收。由于节点的堆栈线程少(其他框架也采用了一种流行的改进方法),此组件中只有一个线程池,它具有 maxThreads 和 minThreads 设置。
其中 address 属性是由成员组件向其他节点广播的主机地址。

消息发送:

<Sender className="org.apache.catalina.tribes.transport.ReplicationTransmitter"><Transport className="org.apache.catalina.tribes.transport.nio.PooledParallelSender"/>
</Sender>

该 Sender 顾名思义就是负责接消息的发送,Sender 有一个shell组件ReplicationTransmitter,但是在子组件 Transport 中完成工作的。一个节点中支持 Sender pool,以便消息的并行发送,使用 NioSender ,也可以实现消息的滨兴发送。
同时:同时向多个 Sender 发送一条消息。
并行:并行向多个 Sender 同时发送多条消息。

拦截器:

<Interceptor className="org.apache.catalina.tribes.group.interceptors.TcpFailureDetector"/>
<Interceptor className="org.apache.catalina.tribes.group.interceptors.MessageDispatchInterceptor"/>
<Interceptor className="org.apache.catalina.tribes.group.interceptors.ThroughputInterceptor"/>

在节点中使用堆栈进行消息的发送。在堆栈中的每个元素都称为拦截器,其工作方式与 Tomcat servlet 容器中的 Valve 非常相似。
使用拦截器后,其业务逻辑可以分解为更易于管理的代码片断。常用的三种拦截器:
1、TcpFailureDetector - 通过 TCP 验证集群中的节点是否挂掉,如果组播中的数据包被丢弃,这个拦截器作用是防止被误报(即使该节点仍然活着并且正在运行,但是被误标记为崩溃的节点)。
2、MessageDispatchInterceptor - 将消息分派给线程(thread pool)以便异步消息发送。
3、ThroughputInterceptor - 输出简单消息流量统计信息。
注意:拦截器的顺序很重要。在 server.xml 中是以堆栈表示的方式。把它们想象成一个链表的形式,头部是第一个拦截器,尾部是最后一个。

集群请求跟踪:

<Valve className="org.apache.catalina.ha.tcp.ReplicationValve"filter=".*\.gif|.*\.js|.*\.jpeg|.*\.jpg|.*\.png|.*\.htm|.*\.html|.*\.css|.*\.txt"/>

在集群中配置 Valve 来跟踪对 Web 应用程序的请求,在上面已经提到了 ReplicationValve 和 JvmRouteBinderValve。
<Cluster> 元素本身不是 Tomcat 中管道的一部分,而是集群将 Valve 添加到其父容器。如果在 <Engine> 元素中配置了 <Cluster> 元素,则需要将 Valve 添加到 Engine 下。

支持远程部署:

<Deployer className="org.apache.catalina.ha.deploy.FarmWarDeployer"tempDir="/tmp/war-temp/"deployDir="/tmp/war-deploy/"watchDir="/tmp/war-listen/"watchEnabled="false"/>

Tomcat集群默认支持远程部署,即可以在其他集群节点上部署和取消部署应用程序。
这个组件的状态处于不断变化之中,但很快就解决了。Tomcat 5.0 和 5.5 之间的部署方法发生了变化,此时该组件的逻辑已更改为部署目录必须与 webapps 目录匹配的位置。

监听器:

<ClusterListener className="org.apache.catalina.ha.session.ClusterSessionListener"/>

由于 SimpleTcpCluster 本身是 Channel 对象的“ 发送者 ” 和 “ 接收者 ”,因此组件可以将自己注册为 SimpleTcpCluster 的监听器。
上面的 ClusterSessionListener 监听器监听 DeltaManager 复制消息,并将 Delta 应用于 Manager,然后将其应用于 Session。

理解 Tomcat 集群如何运行的
为了便于理解群集如何工作的,这儿使用两个 Tomcat 实例 ,即 TomcatA 和 TomcatB 。操作内容如下:
1、TomcatA 启动
2、TomcatB 启动(等待 TomcatA 启动完成)
3、TomcatA 收到一个请求,会话 S1 被创建
4、TomcatA 崩溃
5、TomcatB 收到会话请求 S1
6、TomcatA 启动
7、TomcatA 接收到一个请求,在会话(S1)上调用 invalidate
8、TomcatB 接收请求,进行新会话(S2)
9、TomcatA 会话 S2 由于不活动而过期(这儿就需要重新登录了)

有了一个大致的提纲后,下面我们进行详细的介绍:

1、TomcatA 启动
Tomcat 使用标准启动序列启动。当创建 Host 对象时,将与它关联一个集群对象。在解析上下文时,如果 web.xml 中定义了 distributable 元素,Tomcat 会询问 Cluster 类(在本例中 SimpleTcpCluster )为复制的 <Context/> 中创建 Manager。
因此,启用集群后,可以在 web.xml 中设置可分发的数据集, Tomcat 将为该 <Context/> 创建一个DeltaManager,而不是一个 StandardManager。群集还将启动 Membership  服务(多播)和 Replication 服务(tcp单播)。

2、TomcatB 启动
当 TomcatB 启动时,它遵循与TomcatA相同的序列。该集群已启动并将建立 membership(TomcatA,TomcatB)。
TomcatB 现在将从群集中已存在的服务器(在本例中 为TomcatA )请求会话状态。TomcatA 响应请求,并且在 TomcatB 开始监听 HTTP 请求之前,status 已从 TomcatA 转移到 TomcatB。
如果 TomcatA 没有响应,TomcatB 将在60秒后超时,并发出日志通知。每个 web 应用程序的会话状态都被转移到它的 web.xml 中。
注意:为了使会话有效的复制,所有的 Tomcat实例都应该配置相同。

3、TomcatA 收到一个请求,会话 S1 被创建
对 TomcatA 的请求与没有会话复制的处理方式完全相同。当请求完成时,ReplicationValve 会在将响应返回给用户之前拦截请求。
此时 TomcatA 发现会话已被修改,并且它使用 TCP 将会话复制到 TomcatB。一旦序列化的数据被传递到 TCP 逻辑,请求就会通过 Valve 管道返回给用户。
对于每个请求,整个会话都被复制,这允许在会话中修改属性的代码,而不需要复制 setAttribute 或 removeAttribute。可以使用 useDirtyFlag 配置参数来优化会话复制的次数。

4、TomcatA 崩溃
当TomcatA崩溃时,TomcatB 收到一个通知,TomcatA 已经退出集群。TomcatB 从其成员列表中删除 TomcatA,TomcatA 将不再收到 TomcatB 发生的任何更改通知。
负载均衡器会将来自 TomcatA 的请求重定向到 TomcatB,并且所有会话都是最新的。

5、TomcatB 收到会话请求 S1
TomcatB 将处理请求作为任何其他请求。

6、TomcatA 启动
在 TomcatA 启动之后,在 TomcatA 开始接受新请求并使其可用之前,将遵循上述1)2)所述的启动顺序。
TomcatA 将加入集群,并与 TomcatB 联系以获取当前所有会话的状态。一旦它收到会话状态,它就完成加载并打开它的HTTP / mod_jk端口。
因此,在 TomcatB 接收到会话状态之前,没有任何请求会到达 TomcatA。

7、TomcatA 接收到一个请求,在会话(S1)上调用 invalidate
无效的调用被拦截,并且会话在无效会话中排队。当请求完成时,不再发送已更改的会话,而是向 TomcatB 发送一条 “ 过期 ” 的消息,并且 TomcatB 也会使该会话失效。

8、TomcatB 接收请求,进行新会话(S2)
与步骤3中相同的场景)

9、TomcatA会话S2由于不活动而过期
无效的调用被拦截,就像用户会话无效时一样,会话被无效会话排队。此时,无效会话将不会被复制,直到另一个请求通过系统并检查无效队列为止。

Membership : 群集 Membership 使用非常简单的组播 ping 建立。每个 Tomcat 实例将定期发送一个多播 ping,在 ping 消息中,实例将广泛地将其 IP 和 TCP 监听端口进行复制。
如果在集群中一个实例在给定的时间范围内没有收到这样的 ping,则该成员被认为是死的。非常简单,而且非常有效!当然,只需要在系统上启用多播。

TCP Replication : 一旦接收到组播 ping,member 就会被添加到集群。
在下一个请求时复制,发送实例将使用 Host 和 Port 信息并建立一个TCP Socket。使用这个 Socket,它将发送序列化后的数据。

分布式锁定和使用框架页面 : Tomcat 不会保持会话实例在群集中同步。这种逻辑的实现会花费很多开销并导致各种问题。
如果在客户端使用多个请求同时访问同一会话,则最后一个请求将覆盖集群中的其他会话。

Apache Tomcat 官网: https://tomcat.apache.org/tomcat-9.0-doc/cluster-howto.html

Windows下搭建Tomcat集群的配置详解相关推荐

  1. windows下搭建mysql集群_Windows下搭建MySQL集群

    本文将讨论在Windows下搭建MySQL集群的步骤和搭建过程中应当注意的问题. 由于机器数量和性能有限,搭建环境为一台宿主机(IP:10.200.178.191),一台虚拟机(IP:10.200.1 ...

  2. redis cluster 集群 安装 配置 详解

    redis cluster 集群 安装 配置 详解 张映 发表于 2015-05-01 分类目录: nosql 标签:cluster, redis, 安装, 配置, 集群 Redis 集群是一个提供在 ...

  3. Redis集群搭建(转自一菲聪天的“Windows下搭建Redis集群”)

    配置Redis参考:http://blog.csdn.net/zsg88/article/details/73715947 使用Ruby配置集群参考:https://www.cnblogs.com/t ...

  4. Windows下搭建Redis集群

    一.首先下载好Redis的Windows版本,注意:Redis只有3.0之后的版本才有集群 1.下载好后直接解压,可看到这些目录   2.在解压的目录启动redis-server.exe启动redis ...

  5. 深入分析redis cluster 集群安装配置详解

    Redis 集群是一个提供在多个Redis间节点间共享数据的程序集.redis3.0以前,只支持主从同步的,如果主的挂了,写入就成问题了.3.0出来后就可以很好帮我们解决这个问题. 目前redis 3 ...

  6. LVS集群应用配置详解

    一. 目录 关于集群的介绍. 什么是负载均衡以及为什么需要负载均衡. 负载均衡技术的特点. 负载均衡集群的常见解决方案. lvs介绍及管理工具. 实现lvs集群服务的三种类型方法介绍. LVS调度算法 ...

  7. Hadoop-2.5.2集群安装配置详解

    转载请注明出处:http://blog.csdn.net/tang9140/article/details/42869531 最近学习了下hadoop的安装.下面详细说明下步骤 一.环境 我的是在Li ...

  8. Elasticsearch集群节点配置详解

    注意:如果是在局域网中运行elasticsearch集群也是很简单的,只要cluster.name设置一致,并且机器在同一网段下,启动的es会自动发现对方,组成集群. 三.配置浅涉 elasticse ...

  9. ABAQUS有限元仿真计算工作站单机多核/多机多核集群硬件配置详解

    ABAQUS有限元软件用于分析复杂的固体力学.结构力学系统,特别是庞大复杂的问题和模拟高度非线性问题:其解决问题的范围从相对简单的线性分析到许多复杂的非线性问题.作为通用的模拟工具, ABAQUS 除 ...

最新文章

  1. JMeter打开脚本报错处理方法
  2. (08) 需求征集 -- 消息管理
  3. 小波变换和motion信号处理(三)(转)
  4. pdf 奇数页插入页码_如何在Word 2013中的奇数页码上启动新部分
  5. python实训英文_GitHub - MiracleYoung/You-are-Pythonista: 汇聚【Python应用】【Python实训】【Python技术分享】等等...
  6. 截取全部数值字符并将其转化为数值类型
  7. springboot启动太慢优化
  8. Linux用户相关的操作命令
  9. 怎么用百度搜索php网站,PHP简单获取网站百度搜索和搜狗搜索收录量的方法
  10. JAVA的延时函数使用
  11. 即刻APP所有用户信息爬虫
  12. 登录业务的演变、单点登录(SSO)的三种解决方案
  13. matlab 图像 变成二维,matlab三维图像变二维
  14. 【imx6ul】从头搭建imx6ul开发环境(uboot、内核编译及烧入、mfgtools详细使用方法)
  15. kubuntu16.04安装和卸载fcitx输入法
  16. Windows10 pycharm 前进后退快捷键配置
  17. 在vue中使用iconfont多色图标
  18. 华为服务器RH2288 V2 BIOS配置
  19. 五位本科生4个月造出芯片毕业!新的后续来了……
  20. cuda编程环境搭建

热门文章

  1. linux防ddos 软件下载,linux系统防ddos攻击工具
  2. 报告称:你的智能家居设备每周可能遭受10000次黑客攻击
  3. 2018安卓巴士开发者大会打造Android技术盛宴
  4. 计算机课玩的小游戏,电脑课必玩3款单机游戏,CS玩的紧张,最后一款每台电脑都有!...
  5. java 异步模型_Java IO编程全解(三)——伪异步IO编程
  6. 二、Mutisim仿真软件使用
  7. 考研英语单词-近义词分类-Third Day
  8. cocos creator简单实现打字机效果
  9. kill 杀不死进程的原因
  10. 题录 endnote 导入 NoteExpress