JavaWeb开发:从购买服务器到简单demo运行
写这篇文章的目的:
- 一个是为了记录实施过程,方便自己日后查阅;
- 另一个是给项目组成员提供一个参考,方便他们以后搭建自己的项目环境;
- 当然若能帮助到更多的朋友,那就再好不过了:D
需要注意:
- 我本身也是个初学者,文章中也描述了我在实施过程中的所思所想,但由于能力有限,内容可能并不全面,也可能包含错误;
- 我不会对所有内容都详细描述(那样会导致文章篇幅太长),但是我会提供在实施时所参考的资料;
- 我希望以一个宏观的流程来展示文章内容,会对里面所涉及的细节有的放矢
目录
- 一 背景
- 二 你好!阿里云
- 2.1 购买域名和服务器
- 2.2 域名绑定
- 三 磨刀霍霍向Jetty
- 3.1 安装Java运行环境
- 3.2 安装Jetty
- 四 呵呵,无法访问?
- 4.1 服务器防火墙
- 4.2 阿里云防火墙
- 五 黑站?ICP备案
- 六 丑陋的端口 与 HTTPS
- 七 MySQL走起来
- 7.1 MySQL安装
- 7.2 远程连接测试
- 7.3 题外话:MySQL8新加密方式引起的兼容问题
- 八 Windows下项目开发环境搭建
- 8.1 IntelliJ IDEA
- 8.2 MySQL & MySQL Workbench
- 8.3 Jetty
- 8.4 Maven
- 九 简单demo与项目发布
- 9.1 简单demo
- 9.2 项目发布
- 十 后记
一 背景
- 由于学院工程实践课题需要,我们小组需要开发一个网站,而大家在这方面经验有所欠缺,所以经验比较“丰富”的我就先来试试水,想着试试能不能先整体走一遍流程;
- 而在这之前,我虽然有过Web开发经历,但都是在校课程,服务器都是放在本机上的,就是那种localhost:8080访问的网站;
- 在做好一系列技术选型之后,我就开始了“建站之旅”...
二 你好!阿里云
2.1 购买域名和服务器
很早之前就听说了阿里云对学生有优惠政策,买服务器挺便宜的,所以服务器选了阿里云,域名也是在万网买的:
学生认证这一步我就不多说了,根据阿里云网站的提示就可以进行,如果不满足优惠条件也无妨,有钱就行😂
服务器我买的是:轻量级应用服务器(系统镜像:Ubuntu 16.04 64位,位置:华东2),具体选择还是根据大家的需求。由于学校是在华东地区,所以我选了华东2(服务器在上海)。
如果大家不确定该服务器是否符合自身要求,可以先购买1个月(9.5¥)试试,觉得不错的话后面可以续费。我就是这样先买了1个月,后面又续了1年(总共花了123.5¥),也是因为项目的开发周期比较长的原因。注意:一个账号只能拥有一台优惠政策的云服务器
2.2 域名绑定
注意:绑定前,你的域名需要先进行实名认证(有一些域名可以不用,由于我注册的是.cn的域名,所以需要认证)
当你获得域名和服务器后,在阿里云首页,右上角点击【控制台】,进入控制台管理界面:
然后左上角,选择【产品与服务】,在展开的页面中找到最近访问的【轻量级应用服务器】:
进入你的系统镜像后,在【概览】模块的【应用搭建】中,【站点设置】就会让你绑定域名:
至此,服务器和域名这部分搞定!:D
三 磨刀霍霍向Jetty
3.1 安装Java运行环境
- JDK下载网址:https://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html
- Java环境安装参考教程:Ubuntu 16.04下Java环境安装与配置
- 远程连接工具(Putty下载网址):https://www.chiark.greenend.org.uk/~sgtatham/putty/latest.html
- 上传工具PSCP使用教程:使用PuTTY在Windows中向Linux上传文件
- 阿里云用户指南:远程连接到Linux操作系统实例
注:由于项目后期要使用ssm(spring版本是5.0,支持到java9),但java9好像被抛弃了,所以就选了java8 8u192版本(尽量保持版本一致)
3.2 安装Jetty
在云服务器上安装Web服务器,我选的是Jetty(大公猫我用了好多次了,这次换一换)
下载完后,用工具上传到服务器,或者有下载链接的话可以直接在服务器上使用wget命令下载。
比如我下载的是:jetty-distribution-9.4.12.v20180830.tar.gz
- 解压该文件:>tar -zxvf jetty-distribution-9.4.12.v20180830.tar.gz
- 把解压后的文件夹放到/opt/目录下:>sudo mv jetty-distribution-9.4.12.v20180830 /opt/
- 为了看起来简洁,可以修改目录名称(在/opt/目录下执行):>sudo mv jetty-distribution-9.4.12.v20180830 jetty-9.4.12
- 开启服务器:>/opt/jetty-9.4.12/bin/jetty.sh start
- 虽然可以按 ctrl+c 退出当前进程,然后继续在本窗口(session)下执行其他命令,但是建议另开一个窗口:使用putty再新建一个连接
- 测试服务是否成功开启:使用netstat命令检查端口是否处于监听状态(Jetty默认端口为8080):>netstat -an | grep 8080
- 修改jetty的默认端口号:https://www.cnblogs.com/freeweb/p/5943034.html
四 呵呵,无法访问?
开启jetty服务器后,我就迫不及待地在我本机浏览器上输入:http://mydomainname:8090/(mydomainname是我的域名,我把jetty服务器端口改为了8090),结果却是无法访问!
4.1 服务器防火墙
那么问题出在哪里呢?
- 首先我测试了网络是否连通:>ping mydomainname (发现是可以的)
- 网络是连通的,那么就可能是端口的问题?但我端口也在监听状态了啊!好的,那就是 防火墙 这位大兄弟搞的鬼了!
- putty连接上服务器,查看了防火墙状态...防火墙默认没有开启?!先不管了,开启防火墙,允许8090端口访问(就这样我成功地避开了解决问题的关键点)
- 查看防火墙状态:>sudo ufw status
- 防火墙允许8090端口:>sudo ufw allow 8090
- 后来发现,只允许8090端口访问,你连ssh都连接不上,所以我又设置了防火墙,把常用的端口:80(HTTP)、443(HTTPS)、22(SSH)都设置为允许访问
大功告成(想太美)!再次迫不及待地在浏览器输入:http://mydomainname:8090/,???还是无法访问?!wtf ?
4.2 阿里云防火墙
这又是什么原因呢?这次真是查了不少资料:
- 既然还是无法访问,并且服务器IP可以ping通,那就是端口的原因,然而我的端口已经开启,并且服务器上防火墙也设置了,所以是哪里出错了?
- 虽然端口开启了,但是我还没有测试过端口是否能正常访问:
- 在windows下,使用telnet可以测试:>telnet mydomainname 8090
- 但是我电脑上(win10)不知道为啥,telnet装不上,点开【启用或关闭Windows功能】就一直显示在加载状态,所以我放弃使用telnet进行测试
- 后来由于我安装了git bash,所以用ssh测试了端口是否连通:>ssh -v -p 8090 mydomainname (结果是:Connection timed out,说明端口未连通)
- 我对ssh测试的结果还是半信半疑,又继续查资料,查到了nmap工具,所以我又在Linux服务器上装了nmap,然后直接:>nmap mydomainname,结果是:
- 22/tcp open ssh
- 80/tcp closed http
- 443/tcp closed https
- 这次我信了,果然端口未连通
- 为什么呢?我继续查资料,不经意间看到类似“阿里云为用户提供方便的防火墙设置功能”的词条,点进去一看!!原来是 阿里云防火墙 搞的鬼!!
事实就是:在购买的服务器之外,还有一层防火墙(阿里云防火墙)来控制外界对服务器的访问,如图:
找到了问题根源, 解决起来就很方便了:
添加完规则后,输入网址:http://mydomainname:8090/,再次访问,出现下面的结果,说明访问成功!(由于是后期才来写的博客,之前没有注意收集素材,所以有些不方便暴露的内容,我打了马赛克)
然而“好景不长”,再次刷新页面后,便出现了:
原因很明显了:你的网站需要备案:打开网站后显示:温馨提示,该网站暂时无法访问
五 黑站?ICP备案
HTTP使用80端口,根据相关规定,未进行备案的网站,80端口是被禁用的;也不要认为“我的网站不使用80端口就行,不用备案”。你不备案,你的网站就是黑站,工信部随时查你水表,关你服务器。所以为了网站能正常运行,并且不被查水表,还是老老实实备案。
ICP备案也挺简单的,阿里云提供了完备的备案机制:阿里云备案,你只要根据系统的提示进行操作就行。而且工作人员也挺热心的,我第一次提交初审失败了,后来进行多次询问,对方都认真解答,并给出合适建议。从我首次提交初审(2018.11.01)到最终管局审核通过(2018.11.15)花了15天。备案成功后,阿里云会给你发邮件,如果你的网站要开通使用,你还需要根据规定设置相关内容(如:把ICP备案号放到首页页脚等),并且需要进行 公安备案。具体内容,等你收到邮件后,根据提示操作就行。
六 丑陋的端口 与 HTTPS
其实一开始出现“该网站暂时无法访问”页面时,我最先想到的不是备案,而是如何把那个丑陋的8090端口去掉。你访问过互联网中较多网站后就会发现,很少有网站会在网址中要求把端口号也输入进去。那么该怎么做呢?在网上搜索一番后,找到了利器:Nginx
- nginx documentation:http://nginx.org/en/docs/
- 极客学院Nginx讲解系列:Nginx 入门指南
- Ubuntu 16.04安装Nginx以及相关配置
- Ubuntu 16.04安装Nginx
看了入门指南,大概就清楚了Nginx是什么,有什么用。那就赶快进行安装配置吧,不着急,让我们把 HTTPS 这位大兄弟也带上车。
- 因为我选的是阿里云的服务器,所以直接从阿里云上获取1年免费的SSL证书:SSL证书管理控制台
- 从提交证书申请到审核成功,差不多花了1天的时间。审核通过后,证书就变成了 已签发 状态,如图:
- 然后点击【下载】,因为服务器用的是Nginx,所以选择Nginx版本的证书就行
接下来开始配置HTTPS,顺便配置端口映射:
- 首先将下载到的证书(本例是:cert-1540964531179_www.mydomainname_nginx.zip)传到服务器上
- 解压该文件,会得到下面两个文件:
- cert-1540964531179_www.mydomainname.crt
- cert-1540964531179_www.mydomainname.key
- 在/etc/nginx/目录下创建“cert”目录,然后把解压得到的两个文件移动到该目录下:
- /etc/nginx/cert/cert-1540964531179_www.mydomainname.crt
- /etc/nginx/cert/cert-1540964531179_www.mydomainname.key
- 修改nginx.conf文件(位置:/etc/nginx/nginx.conf),添加HTTPS配置
注意:nginx.config 配置,server{...} 是放在 http{...} 当中的,刚开始以为在http{...}外面独立配置,然后服务一直启动失败。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 http { 2 # ssl setting 3 server { 4 ... 5 } 6 }
添加如下配置(由于我对Nginx不熟悉,所以目前只能达到这种程度):
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 # add https ssl [southday 2018.11.1 v1] 2 server { 3 listen 443; 4 server_name www.mydomainname; 5 6 ssl on; 7 8 ssl_certificate /etc/nginx/cert/cert-1540964531179_www.mydomainname.crt; 9 ssl_certificate_key /etc/nginx/cert/cert-1540964531179_www.mydomainname.key; 10 11 ssl_session_timeout 5m; 12 ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4; 13 ssl_protocols TLSv1 TLSv1.1 TLSv1.2; 14 ssl_prefer_server_ciphers on; 15 16 # 这里使用了Nginx的反向代理,将8090端口号隐藏了 17 location / { 18 proxy_pass http://localhost:8090/; 19 } 20 }
- 配置完成后,启动Nginx服务器(或者重启):>sudo service nginx start/reload,如果你的配置文件非法,那就无法成功启动
- 确保你的jetty服务器已经启动,然后可以开始测试,在本机浏览器上输入:https://mydomainname/,发现成功使用HTTPS进行访问
- 进行了nginx代理配置后,你就没必要对外暴露8090端口了。你可以去nmap一下各种网站,会发现大家基本上都只对外暴露80、443端口。
- 通过nginx进行反向代理,可以将请求转发到本机(localhost或者内网地址),比如本例中就是将请求转发到了:http://localhost:8090/
- 所以你可以把之前防火墙开启的8090端口关了,访问视图如下:
注:后期ICP备案成功后,要用Nginx把80端口映射到443端口。好多网站都是这样做的,比如你输入网址:http://www.baidu.com/ 访问,会被默认转成:https://www.baidu.com/
参考内容:
- Nginx反向代理之端口转发
- nginx 80端口重定向到443端口
- Nginx的location配置规则梳理
- nginx设置支持https请求(阿里云服务器)
- nginx配置https(免费证书)
- 阿里云https+nginx服务搭建
- 教你把HTTP网站免费转成HTTPS网站
- 阿里云HTTPS加密访问
七 MySQL走起来
7.1 MySQL安装
是时候安装数据库了:D,个人觉得官方的安装教程就很全面了:
- A Quick Guide to Using the MySQL APT Repository
- Chapter 2 Installing and Upgrading MySQL
- 2.5 Installing MySQL on Linux
- Download Connector/J(后期你可能会用到)
- Maven MySQL Connector/J
7.2 远程连接测试
实际开发中,关于数据库部分的内容,我接触过的开发过程是这样的:
- 开发人员使用VPN连接到测试环境DB,然后在测试环境进行一系列开发;
- 开发完一个模块后,提交给测试小组、用户等测试;
- 测试通过后,从测试环境DB中导出SQL脚本;
- 在合适的时间(官方宣布系统升级或晚上大家都睡了的时候),开发人员把SQL脚本放到正式环境DB上执行(当然还会包括其他一些应用的部署);
这些过程,随着项目逐渐庞大,就会演化出一个自动化部署系统,现在就有一些用于持续构建(CI/CD)的工具,比如:Jenkins。虽然我没有搭建VPN,并且会把3306的端口暴露给外界,但是对于几个学生一起做的小项目,大家共享数据库内容所得的好处,要比因过早考虑安全性等因素而造成开发不便好得多。可以等开发完成后把端口关了,或者后期自己搭个VPN也行。
进入正题吧:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 # 首先确保mysql已启动 2 >sudo service mysql start 3 4 # 命令行登陆mysql 5 >mysql -u root -p 6 7 # 创建database 8 create database test_db; 9 use test_db; 10 11 # 创建表 12 create table tools( 13 tool_name varchar(20), 14 description varchar(30)); 15 16 # 插入数据 17 insert tools values('Eclipse', 'Java IDE'); 18 insert tools values('Sublim Text', 'A light weight editor'); 19 20 # 创建用户 21 create user 'lcx'@'%' identified by 'southday'; # '%'表示允许所有主机连接 22 grant all privileges on test_db.* to 'lcx'@'%'; 23 24 # 刷新权限 25 flush privileges;
然后在windows下使用MySQL Workbench进行远程连接(关于windows下安装mysql,我会在下文给出部分内容):
注意:要记得把 服务器防火墙 和 阿里云防火墙 都设置允许 3306 端口访问!
7.3 题外话:MySQL8新加密方式引起的兼容问题
对于使用了新的加密方式,而无法兼容(老程序访问不了新数据库),解决办法简单总结如下:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 1.将加密方式改为旧的,在配置文件my.conf中添加如下: 2 [mysqld] 3 default_authentication_plugin=mysql_native_password 4 5 2.使用支持新的加密方式的客户端(Client),比如等于或高于8.0.4版本的libmysqlclient 6 7 3.使用支持新的加密方式的连接驱动(Connector): 8 MySQL Connector/C++ 1.1.11 or higher or 8.0.7 or higher. 9 MySQL Connector/J 8.0.9 or higher. 10 MySQL Connector/NET 8.0.10 or higher (through the classic MySQL protocol). 11 MySQL Connector/Node.js 8.0.9 or higher. 12 PHP: the X DevAPI PHP extension (mysql_xdevapi) supports caching_sha2_password. 13 14 4.使用了新的加密方式,改为旧的加密方式,root用户也要进行相应的更改才可以,因为root用户还是新的加方式,所以使用alter语句改为重置密码来覆盖新的加密方式的密码: 15 ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY 'password'; 16 password是你将要设置的root用户的密码。
参考内容:
- MySQL安装及MySQL8.0新密码认证方式
- caching_sha2_password Compatibility Issues and Solutions
- 今天遇到的mysql8.0的新特性(坑)和解决办法
- Mysql| 命令行模式访问操作mysql数据库
- MySQL创建用户与授权
- MySql—修改权限
八 Windows下项目开发环境搭建
8.1 IntelliJ IDEA
学生党优惠无处不在😂:
- 使用学校邮箱申请了GitHub学生包:GitHub student developer package
- 认证成功后(4-5天),通过该平台(GitHub)访问JetBrain:https://www.jetbrains.com/student/?authMethod=github
- 然后你就可以下载安装JetBrian系列产品了(我的License期限是1年)
8.2 MySQL & MySQL Workbench
windows下安装MySQL挺简单的,不用过多描述,只不过如果你下载的是免安装版本,就会有些坑等着你。
如果你下载的是免安装版的,那么你可能会需要:
8.3 Jetty
- windows下安装Jetty和ubuntu下安装差不多,就是下载好解压包,然后解压即可使用。(Jetty下载)
- 解压后,命令行进入jetty目录,执行命令:>bin\jetty.sh start,即可启动服务
8.4 Maven
- Maven下载:http://maven.apache.org/download.cgi
- 修改Maven相关配置(settings.xml),比如本例:D:\Maven\apache-maven-3.5.4\conf\settings.xml
- 设置本地仓库位置
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 <!-- localRepository 2 | The path to the local repository maven will use to store artifacts. 3 | 4 | Default: ${user.home}/.m2/repository 5 < >/path/to/local/repo</localRepository> 6 --> 7 <localRepository>D:/MavenRepo</localRepository>
- 设置镜像仓库(阿里),如果使用国外镜像的话,下载速度可能会慢一些
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 <mirrors> 2 <!-- mirror 3 | Specifies a repository mirror site to use instead of a given repository. The repository that 4 | this mirror serves has an ID that matches the mirrorOf element of this mirror. IDs are used 5 | for inheritance and direct lookup purposes, and must be unique across the set of mirrors. 6 | 7 <mirror> 8 <id>mirrorId</id> 9 <mirrorOf>repositoryId</mirrorOf> 10 <name>Human Readable Name for this Mirror.</name> 11 <url>http://my.repository.com/repo/path</url> 12 </mirror> 13 --> 14 <!-- 配置镜像仓库后,原仓库不会被访问--> 15 <mirror> 16 <id>alimaven</id> 17 <mirrorOf>central</mirrorOf> 18 <name>aliyun-maven</name> 19 <url>http://maven.aliyun.com/nexus/content/groups/public</url> 20 </mirror> 21 </mirrors>
当然你也可以使用 IDEA 自带的Maven插件,我个人比较推荐安装本地Maven,然后在IDEA上设置使用本地Maven
九 简单demo与项目发布
9.1 简单demo
项目采用的开发框架是:Spring + SpringMVC + Mybatis,其他的:Maven + Jetty + MySQL。由于篇幅关系,我只给出demo源码,关于实施过程,我会给出我参考过的资料。demo很简单,就是根据用户输入的关键字进行查询,然后数据库返回数据,后端将数据转为json格式返回给前端。
demo下载:ssm-demo-idevtools.zip 提取码:kzvv
强调:demo很简单,程序不够健壮,异常处理机制也不完善,大家看看就好,生产环境中可不能像demo中那样写:D 并且要根据实际情况修改部分代码,直接搬过去估计会出错:D
9.2 项目发布
在windows下开发好后,使用Maven将项目打成war包,然后上传到Linux服务器,把war包放到jetty安装目录的webapps文件夹中。启动nginx服务器、jetty服务器、mysql,然后在本机输入网址就能访问。在此过程中,你可能又会根据自身需要去修改 nginx.conf 中的相关配置,good luck:D
参考内容:
- Mybatis
- SSM
- Maven
- 其他
十 后记
虽然整体流程走通了一遍,但还是有较多不足之处,比如:
- 异常处理机制不完善,HTTP ERROR 500 的内容随随便便就显示到了浏览器上;
- 由于异常信息显示到了浏览器上,很可能SQL语句也会被暴露给外界,再加上你的SQL存在漏洞,就很容易被不法分子实施SQL注入攻击;
- MySQL超过8小时后自断连接的问题待处理
不瞒大家说,我写的那个demo确实存在SQL注入漏洞,而且我也成功实施了SQL注入(通过添加“or 1 = 1”来返回全部数据),如图:
拼接后的SQL语句为:SELECT * FROM tool_t WHERE tool_name LIKE 'ec' or 1=1 or tool_name = '%';
由于时间比较紧,成功走完一遍流程后,我对这个demo的关注度就少了,上面的3个问题还是只我目前所发现的,我相信还有更多的问题等着我们去解决。选择了就去面对,就这样:D
Emmmmm.....后期有空要做个自动化部署的,每次Maven打包上传服务器,太费劲.... 下次再聊 :D
转载请说明出处,have a good time! :D