热门标签 | HotTags
当前位置:  开发笔记 > 后端 > 正文

JBOSSEAP实战(2)-集群、NGINX集成、队列与安全

JBOSSHTTP的ThreadGroup概念JBOSS是一个企业级的J2EEAPPContainer,因此它和任何一种成熟的企业级中间件一样具有ThreadGroup的概念。

JBOSS HTTP的Thread Group概念


JBOSS是一个企业级的J2EE APP Container,因此它和任何一种成熟的企业级中间件一样具有Thread Group的概念。
所谓Thread Group就是一个HTTP队列机制,利用Thread Group在JBOSS内可以设置如“阻断”,“升级”,“降级”等机制。
来看一个这样的实际应用场景:
当你的JBOSS连着一堆核心应用时,此时突然你的HTTP的并发请求在某一个点激增,如果把这些HTTP请求都放进后台,那么将意味着你所有的核心模块将会受到严重的影响,因此一般来说对于这样的场景我们会采取如下的几种措施:

  1. 阻断,除去定额的请求,其它请求进不进来,即抛弃策略
  2. 队列,除去定额的请求,其它请求排队,排队排到前端超时,出错
  3. 自动扩展,即给定一个定额的最大请求数,当超过这个请求数后Container会根据自身服务器的能力自动扩展

JBOSS的Thread Group的种类


在JBOSS里使用的正是Thread Group来支持这几种机制的,我们来看一下这几种机制在JBOSS中的实现:

  • unbounded-queue-thread-pool
  • bounded-queue-thread-pool
  • blocking-bounded-queue-thread-pool
  • queueless-thread-pool
  • blocking-queueless-thread-pool
  • scheduled-thread-pool

做过开发的相信一眼就看出来,其实这6种JBOSS提供的HTTP Thread Group正是JAVA多线程内ConcurrentThreadPool的线程种类。


本文对6种线程不做一一探讨,他们的区别从字面上相信读者可以马上理解,在配置时参数略有不同,对于每个不同种类的Thread Group读者可以自行通过JBOSS官方文档(如下URL)获取它们的区别:
https://developer.jboss.org/wiki/ThreadPoolConfiguration


本文只作JBOSS EAP6中如何进行Thread Group的配置。


动手配置一个Thread Group



打开$JBOSS_HOME/standalone/configuration/standalone.xml文件


找到这句,把它改成:


            








找到这句,再往下找到:



重启JBOSS即可



用Security Domain保密认证信息



为什么要加密? 我们来看下面这个例子:


                                        jdbc:mysql://192.168.0.101:3306/guvnor                    mysql                                            。。。                                            drools                        password_1


虽然,你可以说这个配置文件是位于企业内网的,内网就安全了?万一有有心人。。。因为安全的宗旨是“宁可信其有(小偷),不可信其无”。


因此一般来说在生产环境我们是需要对这个配置文件中的敏感信息进行加密的。


JBOSS对配置文件中的加密有两种方式:


1.  Picketbox(推荐全部用这种方式)
2.  Vault(不适合于DOMAIN模式、很繁琐)



用Security Domain保密认证信息-Picketbox方式



确保你使用的是JBOSS EAP6.2-6.4或者更高版本,在Linux中启动一个shell,敲入如下命令行:


export JBOSS_HOME=/opt/jbossexport CLASSPATH=${JBOSS_HOME}/modules/system/layers/base/org/picketbox/main/picketbox-4.1.1.Final-redhat-1.jar:${JBOSS_HOME}/modules/system/layers/base/org/jboss/logging/main/jboss-logging-3.1.4.GA-redhat-2.jar:$CLASSPATHjava  org.picketbox.datasource.security.SecureIdentityLoginModule EncryptedPassword


此处的”EncryptedPassword”就是我们需要加密的“明文”,接下去它会输出如:


Encoded password: -6e9c0a6a3bb1e4c0


这边的“Encoded password:”后的就是被加密后的密文


然后,我们需要建立一个Security-Domain,我们在段下找到


 
               


由于我们用的是domain模式启动的jboss,因此,你不能找到一个”security-domains”就去改,因为domain模式是根据profile name来区分配置段的,如果你的security-domain加在default下,而启动使用的是full模式那么你的配置是无效的。

我们在

               


段下加入

                                                                                                                                                                        



有了security-domain我们就可以在我们的配置中应用它了,如我们在datasource配置处使用security-domain


                                                jdbc:mysql://192.168.0.101:3306/guvnor>                        mysql                                                            。。。                                                                            encrypted-ds                        


用Security Domain保密认证信息-vault模式

使用vault模式要求我们先需要在JBOSS中建立自己的VAULT,我们使用如下命令:


$JBOSS_HOME/bin/vault.sh

出现如下字符界面:


JBoss Vault
JBOSS_HOME: /Volumes/Disk01/appservers/center/jboss-eap-6.1
JAVA: java
============================================================
**********************************
****  JBoss Vault  ***************
**********************************
Please enter a Digit::   
0: Start Interactive Session  1: Remove Interactive Session  2: Exit


按选0


Enter directory to store encrypted files:[输入] ../vault/


Enter Keystore URL:[输入] ../vault/ymkeyes.keystore
Enter Keystore password: [输入]aaaaaa
Enter Keystore password again: [输入]aaaaaa
Enter 8 character salt: [输入]12345678
Enter iteration count as a number (Eg: 44): [输入]44
Enter Keystore Alias: [输入] ymkeyes


Initializing Vault
2013-7-18 11:08:02 org.picketbox.plugins.vault.PicketBoxSecurityVault init
INFO: PBOX000361: Default Security Vault Implementation Initialized and Ready
Vault Configuration in AS7 config file:
********************************************

 
       
       
       
       
       
       
   
...
********************************************
Vault is initialized and ready for use
Handshake with Vault complete
Please enter a Digit::   
0: Store a secured attribute  1: Check whether a secured attribute exists  2: Exit


按选0
把上面从开始到这一块复制进standalone.xml文件中,放于段后
对于屏幕中输出的如下信息,注意红色加粗字体即是你用vault加密后的加密串
Secured attribute value has been stored in vault. 
Please make note of the following:
********************************************
Vault Block:ds_MegaeyesDS
Attribute Name:password
Shared Key:MjY5Nzc0OWItMmI2OS00NWMyLTlkZTYtOWY0MWE5YzAyOGMwTElORV9CUkVBS21lZ2FleWVz
Configuration should be done as follows:
VAULT::ds_oracleds::password::MjY5Nzc0OWItMmI2OS00NWMyLTlkZTYtOWY0MWE5YzAyOGMwTElORV9CUkVBS21lZ2FleWVz
********************************************

有了VAULT,你就可以在你的配置文件中如我们在中,如下配置:


                                    jdbc:mysql://192.168.0.101:3306/guvnor                    mysql                                            10                        25                        IdleConnections                                                                drools                        ${VAULT::ds_oracleds::password::1}                    

注意加密串还要前后加上 ${加密串}才可生效


可以看出,使用这种方式的加密,太繁琐,而且它不支持DOMAIN模式即不可使用在集群环境中。


JBOSS集群



啊。。。集群,又是集群。


JBOSS集群是从3.X开始那差不多是在14年前就开始支持集群了。


目前的JBOSS EAP6.2-6.4或者是JBOSS8.0(WILDFLY)对于集群的支持已经到了登峰造极的地步了,而且最主要的是JBOSS的集群具有以下特色:


  • 任意横向、纵向折分
  • JBOSS VM-JBOSS自己可以虚拟出一堆的JBOSS来
  • 集中管控,即Controller,利用这一点它可以做到一点布署多点应用,这种集中统一布署的功能只有在IBM的WAS中才具有,即Domain Management的功能



JBOSS集群-横向纵向折分


试想一下这种架构:





如果在这个架构中任何一个SLAVE发生了宕机,那么对于整个集群来说用户的访问是依旧可以用的。


但是,我们试想一下,如果JBOSS MASTER都宕机了呢?




于是,我们有了如下的架构:




这样,在任意一点发生不可预料的宕机时,我们的整个集群的服务还是持续可用的只要不是所有的节点都宕掉。


所谓横向、纵向




JBOSS可以纵横交错,任意划分出无数台“JBOSS虚拟机”从而构成一个“网状”结构


由于JBOSS采用了类似于IBM WAS的域控理念,因此它可以做到“集中统一布署”,即只要在主控端发布一个程序,该主控端下属所有的MASTER、SLAVER全部会自动布署。而这个自动化“分发”的过程,是不需要人为干涉的。它意味着我们的运维开发不需要一个个手工COPY war包到每个J2EE APP SERVER上去了。






JBOSS虚拟机



JBOSS也引入了时下最时髦的“VM”技术,即你可以启动一个JBOSS Instance,然后在这个JBOSS的Instance中为每一个不同的JBOSS子Container指定它们的参数、甚至JVM核心参数





JBOSS集群搭建



说了这么多,我们就来搭建一个JBOSS集群吧!


先来规划我们的JBOSS集群,在我们的例子中我们不使用JBOSS虚拟机,我们使用2个真正的JBOSS Instance即启动两个不同JVM进程的JBOSS来实现MASTER-SLAVER的模式。


我们先来规划我们的JBOSS集群。




我们建立两个JBOSS实例,使其分别名为:


JBOSS_MASTER1
JBOSS_SLAVE1




JBOSS集群一定用的是DOMAIN模式来去运行的,即$JBOSS_HOME/bin/domain.sh来运行的,因此我们记得把两个JBOSS的$JBOSS_HOME/domain/configuration/host.xml文件中的下面这段:

                                                                                

以上配置中的9999与9990确保两个JBOSS Instance中的这两个端口一定不能一样,如我的slave中的此处配置为:


                                          

你也可以把slave中的host.xml文件COPY一份然后使用host-slave.xml改名成host.xml文件


MASTER和SLAVE的host.xml文件的区别还有一点,来看SLAVE的host.xml文件下面这一处:


         


从这边可以看到slave中有一个段,在这个段内所指向的 ManagementRealm的IP与端口必须是它的master即Master主机中host.xml文件中的ManagementReal所设的IP与PORT。


注意host.xml文件中的头部信息



不要忘了把name很重要!!!


JBOSS集群有一个很重要的步骤,即:


加入每个MASTER的SLAVE,是以JBOSS中的用户名和密码来“认证”的,即每个SLAVE要加入Master,Master必须允许。


因此,此处的host name=“”就是SLAVE 用户名,那么密码呢?


请在JBOSS MASTER所在的目录中运行add-user.sh命令,然后建一个用户名,这个用户名必须=host后的name,另外,在建完用户后把该用户的密码(显示为MD5值)记下,然后在slave所在的host.xml文件中把密码设进去,按照如下例子:





因为JBOSS是以GROUP的概念来管理它的集群的,如下图:




所以我们需要把我们的8080与8081这两台主机加入到一个GROUP中去。


在slave的host.xml文件中增加入下内容


                      



这边几个地方需要注意的:


  • group,如果不同的host属于同一个group,那么它们将同属于一个master管理
  • full-sockets:JBOSS中有ha, full, full-ha 3种profile,我们在此使用的是full模式,相对应的socket为full-sockets
  • port-offset 为端口偏移量,在刚才的步骤中我们对于ManagementRealm中的两个端口是手设的,可是还有其它一堆的端口,多达10几个,我们总不至于一个个去手改吧,因此这边的port-offset为“除去managementreal”中的端口号其它所有端口号(当然不包括一些应用自己在内部开设的一些端口)+1,比如说:master的web端口为8080,那么slave1的web端口就会变为8081, slave2设成port-offset=2那么slave2的web端口就为8082了,是不是很方便?

相应的,在master机上的host.xml文件中也需要有这么一句:


                



配置domain.xml文件,你可以把slave上的domain.xml备份一下,然后把domain-slave.xml文件改名成domain.xml文件来作修改(如果你不是一个熟手的话),事实上JBOSS对于domain.xml和host.xml文件分别提供了master, slave模式供你使用,如果你改坏了,你也可以通过JBOSS对修改过保存过的配置文件自动进行备份和版本控制这个功能来回退。




其实domain.xml文件中主要的是对JBOSS“资源”的配置,如:
datasource,system properties, jvm。


由于JBOSS使用的是Domain Controller模式,因此对于JBOSS中一切资源的使用只需要在Controller上配置即可。


你可以把JBOSS的controller相像成一个“狮子座”,它的占有欲极强。


由于在本例中我们使用的是一台MASTER,一台SLAVE,因此这台MASTER又同时是CONTROLLER,当然在机器富足的情况下你也可以考虑CONTROLLER挂一台MASTER,然后MASTER下再挂一台或者是多台SLAVE。


此处还需要注意的是domain.xml文件很长,它里面有这样的开头:


         

而这样的profile会有3处重复,所不同的是profile name=“full”, profile name=“full ha”,因此你的设的是什么profile,你的需要设置的资源也需要在domain.xml文件中放在哪个profile段。 此例中我们使用的是full,因此我们的DataSource, System Properties等就都放在了这个段里。  


我们之前在MASTER和SLAVE的host.xml文件中分别把2台主机都加入到了一个叫kie-server-group的段,因此我们需要在domain.xml文件中加入一个server group的声明段,如下示例:


                            


此处需要注意的是,如果使用domain模式启动,各group中的jboss实例虽然都各自使用domain.sh命令启动,并且你在domain.sh所调用的环境配置命令domain.conf中设置了如: -Xms6144m -Xmx6144m 这样的JVM参数,但其实你还需要在domain中划分出的不同的jboss实例中再次作一下声明,为什么?


因为JBOSS启动实例用的是domain.sh+domain.conf中JVM所设的JVM参数,而JBOSS真正运行起来后用于RUN相关的布署的应用用的却是JBOSS内的“Domain JVM”,而你在domain.conf中设置的JVM参数只是给JBOSS启动时所使用的,并不是这个JBOSS实例如:运行某个布署的.war包时所使用的真正的JVM,而一旦该JBOSS实例加入了某个group时,当这个实例开始布署或者是运行某个.war包或者是.ear包时,如果你没有设过domain jvm参数,那么它的实际可用JVM堆默认只有256MB。


这就是为什么外面很多人说,JBOSS集群一旦启动,发觉本来在单节点运行的好好的web应用在集群环境下却会报out of memory或者是gc overhead limit。


让我们在MASTER和SLAVE上的host.xml文件中为我们的2个JBOSS实例配置虚拟JVM参数吧


Master上的host.xml文件中的设置


                                                                                                       

Slave上的host.xml文件中的设置


            	                                                                                     


全部配完后分别使用:


/opt/jboss_master1/bin/domain.sh


/opt/jboss_slave1/bin/domain.sh


命令把master和slave启动起来吧。


启动后我们打开主控端的WEB管理界面http://192.168.0.101:9990,可以看到如下网络拓扑结构。



其实,嘿嘿!


刚才那一段繁琐枯燥的配置,你也完全可以把MASTER先启动起来后通过http://192.168.0.101:9990界面进入后可视化进行操作,看到这儿有人可能会想“打我”了,可是。。。如果你拿图形界面配过无数次后也能像我一样手配XML文件了,而且手配XML文件。。。速度更快!




在JBOSS集群中布署应用


布署一个应用,在这边我也想用xml文件来讲解。。。可是又怕有人“打我”,但是在集群环境下的布署分为:


.war包


.war格式的目录(exploded war)


而JBOSS的自带的http://192.168.0.101:9990只支持图形化布署.war包。。。不支持布署.war格式的目录,因此我们还是用xml文件配置的方式来说吧(你们最终反正是要把我打一顿的,?)


先来说一下集群环境下的.war包的布署吧,我们以petstore.war来举例,我们把master-slave结构搭完后,直接按照如下步骤操作




JBOSS会把这个变成一个两进制文件并以GUID的方式重命名该文件,并把它置于MASTER的/domain/servers/master_name/data目录。


我们注意这个$MASTER_JBOSS_HOME/domain/server目录,这下面还会有一个slave1的目录,这是JBSOS自动生成的,因此MASTER所挂集群下所有节点的日志、启动信息、布署都必须在此目录内寻找,而不是再手工跑到每个JBOSS节点中去寻找了。这也正是JBOSS的domain controller集中管控思想的体现。


在此步骤,你只是把需要deploy的文件上传到了主控域上且并未开始布署,为了完成真正的布署,你需要点击【Assign】按钮


一旦你点击了Assign按钮后,你会得到一个弹出界面,在此界面内会提示你要把这个.war Assign给哪一个group,此时,一旦当你把一个war Assign给了某个group并点击了【确定】后,JBOSS会作如下的事情:


  • 从Controller开始先布署MASTER
  • 再布署该Controller下所挂的SLAVER、SLAVER中的MASTER,S`SLAVE

如果你的Controller下挂的节点是一颗很复杂的“树”,它也会一键完成所有节点的deploy。


布署完后,我们来查看一下我们的集群应用:



看,2个地址都可以访问了。


使用NGINX来对JBOSS集群作“分发”


网上很多教程使用的都是Apache的mod_模块,相当的繁琐。


与Nginx相比Apache弱到爆了,我们来看一下Nginx是怎么完成对jboss集群的分发的吧。


http {    rewrite_log on;        default_type  application/octet-stream;                   charset  utf-8;              sendfile on;         tcp_nopush     on;   	             keepalive_timeout 60;          tcp_nodelay on;        client_header_buffer_size 4k;         large_client_header_buffers 4 32k;      server_names_hash_bucket_size 128;         upstream j2eeserver {        server 192.168.0.101:8080;      server 192.168.0.101:8081;      }     include       mime.types;        log_format  main  '$remote_addr $remote_user [$time_local] "$request" $http_host '        '$status $upstream_status $body_bytes_sent "$http_referer"'        '"$http_user_agent" $ssl_protocol $ssl_cipher $upstream_addr'        '$request_time $upstream_response_time';    access_log  logs/access.log  main;    gzip on;       gzip_min_length  1k;       gzip_buffers     4 16k;       gzip_http_version 1.1;       gzip_comp_level 2;       gzip_types       text/plain application/x-Javascript text/css application/xml;       gzip_vary on;      server {        listen       80;        server_name  192.168.0.101 localhost;        charset utf-8;        #access_log  logs/host.access.log  main;        location / {            proxy_set_header X-Real-IP $remote_addr;            proxy_set_header Host $host;            proxy_set_header X-Forwarded-Host $host;            proxy_set_header X-Forwarded-Server $host;            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;            proxy_pass http://j2eeserver;        }        error_page   500 502 503 504  /50x.html;        location = /50x.html {            root   html;        }     }

我们来实验一下吧。


cd /usr/local/nginx
./nginx –c /usr/local/nginx.conf


启动后访问:http://192.168.0.101/petstore (此时不用加端口号了)




然后我们在后台,随意杀掉master或者是slave进程




我们来杀master进程吧




重新访问http://192.168.0.101/petstore, look,还是跑得刚刚的!我们的集群成功了。




这边我们也不用作什么动静分离了,就让NGINX全部转发JBOSS的请求即可,因为你公司也不差这点内存、CPU,做什么动静分离。。。non sense!



JBOSS集群中如何布署exploded war


所谓exploded war即“打碎了的war”,意思就是一个文件目录,它是以.war结尾的并且要符合war的目录结构标准。


要布署这样的文件目录形式其实很简单,你只要打开主控域上的domain.xml文件,在其中加入这样的语句,.war目录可以随便置放在何处, wherever u want:


                              

然后回到http://ip:9990 这个图形化界面中就会看到在主控域上有一个.war已经被Deploy,但还没有被Assign,此时你只要做相应的Assign操作即可完成整个JBOSS集群的布署了。


附上Nginx的安装

Nginx需要依赖下面3个包


1. gzip 模块需要 zlib 库 ( 下载: http://www.zlib.net/  )  zlib-1.2.8.tar.gz
2. rewrite 模块需要 pcre 库 ( 下载: http://www.pcre.org/  )  pcre-8.21.tar.gz
3. ssl 功能需要 openssl 库 ( 下载: http://www.openssl.org/  )  openssl-1.0.1.tar.gz


注意:如果用源码安装的话,后面nginx安装的时候需要指定 --with-pcre 对应的压缩包路径


openssl:

    tar -xzvf openssl-1.0.1.tar.gz    cd openssl-1.0.1    ./config(注意) && make && make install


    
pcre:
    tar -xzvf pcre-8.21.tar.gz    cd pcre-8.21    ./configure  && make && make install


    
zlib:
    tar -xzvf zlib-1.2.8.tar.gz    cd zlib-1.2.8    ./configure  && make && make install


通过 http://nginx.org/download/ 下载nginx最新版,本例中使用的是nginx-1.8.1.tar.gz,下载解压后进入nginx源码目录使用下面命令进行一键式编译安装:

./configure --sbin-path=/usr/local/nginx/nginx --conf-path=/usr/local/nginx/nginx.conf --pid-path=/usr/local/nginx/nginx.pid --with-http_ssl_module --with-pcre=../pcre-8.38 --with-zlib=../zlib-1.2.8 --with-openssl=../openssl-1.0.2g --with-http_stub_status_module --user=nginx --group=nginx


全部成功后,在/usr/local目录下就会生成一个nginx目录,nginx就安装在此目录内了。


推荐阅读
  • 这是原文链接:sendingformdata许多情况下,我们使用表单发送数据到服务器。服务器处理数据并返回响应给用户。这看起来很简单,但是 ... [详细]
  • Centos7.6安装Gitlab教程及注意事项
    本文介绍了在Centos7.6系统下安装Gitlab的详细教程,并提供了一些注意事项。教程包括查看系统版本、安装必要的软件包、配置防火墙等步骤。同时,还强调了使用阿里云服务器时的特殊配置需求,以及建议至少4GB的可用RAM来运行GitLab。 ... [详细]
  • 本文介绍了南邮ctf-web的writeup,包括签到题和md5 collision。在CTF比赛和渗透测试中,可以通过查看源代码、代码注释、页面隐藏元素、超链接和HTTP响应头部来寻找flag或提示信息。利用PHP弱类型,可以发现md5('QNKCDZO')='0e830400451993494058024219903391'和md5('240610708')='0e462097431906509019562988736854'。 ... [详细]
  • 一句话解决高并发的核心原则
    本文介绍了解决高并发的核心原则,即将用户访问请求尽量往前推,避免访问CDN、静态服务器、动态服务器、数据库和存储,从而实现高性能、高并发、高可扩展的网站架构。同时提到了Google的成功案例,以及适用于千万级别PV站和亿级PV网站的架构层次。 ... [详细]
  • LVS实现负载均衡的原理LVS负载均衡负载均衡集群是LoadBalance集群。是一种将网络上的访问流量分布于各个节点,以降低服务器压力,更好的向客户端 ... [详细]
  • GSIOpenSSH PAM_USER 安全绕过漏洞
    漏洞名称:GSI-OpenSSHPAM_USER安全绕过漏洞CNNVD编号:CNNVD-201304-097发布时间:2013-04-09 ... [详细]
  • 目录浏览漏洞与目录遍历漏洞的危害及修复方法
    本文讨论了目录浏览漏洞与目录遍历漏洞的危害,包括网站结构暴露、隐秘文件访问等。同时介绍了检测方法,如使用漏洞扫描器和搜索关键词。最后提供了针对常见中间件的修复方式,包括关闭目录浏览功能。对于保护网站安全具有一定的参考价值。 ... [详细]
  • 本文分享了一位Android开发者多年来对于Android开发所需掌握的技能的笔记,包括架构师基础、高级UI开源框架、Android Framework开发、性能优化、音视频精编源码解析、Flutter学习进阶、微信小程序开发以及百大框架源码解读等方面的知识。文章强调了技术栈和布局的重要性,鼓励开发者做好学习规划和技术布局,以提升自己的竞争力和市场价值。 ... [详细]
  • 如何在服务器主机上实现文件共享的方法和工具
    本文介绍了在服务器主机上实现文件共享的方法和工具,包括Linux主机和Windows主机的文件传输方式,Web运维和FTP/SFTP客户端运维两种方式,以及使用WinSCP工具将文件上传至Linux云服务器的操作方法。此外,还介绍了在迁移过程中需要安装迁移Agent并输入目的端服务器所在华为云的AK/SK,以及主机迁移服务会收集的源端服务器信息。 ... [详细]
  • 李逍遥寻找仙药的迷阵之旅
    本文讲述了少年李逍遥为了救治婶婶的病情,前往仙灵岛寻找仙药的故事。他需要穿越一个由M×N个方格组成的迷阵,有些方格内有怪物,有些方格是安全的。李逍遥需要避开有怪物的方格,并经过最少的方格,找到仙药。在寻找的过程中,他还会遇到神秘人物。本文提供了一个迷阵样例及李逍遥找到仙药的路线。 ... [详细]
  • 本文讨论了读书的目的以及学习算法的重要性,并介绍了两个算法:除法速算和约瑟夫环的数学算法。同时,通过具体的例子和推理,解释了为什么x=x+k序列中的第一个人的位置为k,以及序列2和序列3的关系。通过学习算法,可以提高思维能力和解决问题的能力。 ... [详细]
  • 本文介绍了如何将PPT格式转换成PDF,并推荐了一款高效的PPT转换成PDF转换器。该转换器利用最新的超线程技术核心和多核心CPU性能,提高了转换效率和转换质量。同时,该转换器具备万能转换模式,可以轻松实现不同类型、不同内容和不同排版的PPT文件的转换。用户可以通过下载链接获取该转换器。 ... [详细]
  • Harmony 与 Game Space 达成合作,在 Shard1 上扩展 Web3 游戏
    旧金山20 ... [详细]
  • 物联网市场:得安全者得天下
    物,联网,市场,得 ... [详细]
  • 14亿人的大项目,腾讯云数据库拿下!
    全国人 ... [详细]
author-avatar
胡印鉴_473
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有