从ECS到Serverless,开发成长那些事

2020,对所有人来说注定是难忘的一年。

转眼已是八月的尾巴,还未来得及细细品味这夏日时光,开学的日子就又要到来了。我计较这变化的数字,在日常与Bug斗争中忙里偷闲。回忆学习历程,我发现在写代码这件事上,明显感觉到与别人有巨大的差距,许多容易的概念在我这里理解起来变得困难,更多的时候在写代码时一些常用的方法我不得不去依赖搜索引擎找答案。于是每天的写代码的生活逐渐转变为写Bug,但我竟对此仍乐此不疲。

时间拉回到一月份,此时的我正享受着为数不多的寒假。某天夜里我辗转反侧无法入睡后开始思索,自己的知识储备严重不足,没有拿得出手的项目,唯一写过的一个JSP+Servlet的个人博客系统, 似乎已赶不上时代的潮流。再想到开学后学期结束便是大四,就再无心思睡觉,计划着要在剩下的日子里做个像样项目出来。后来查找资料后选定了一个SSM框架的项目,想起自己此前的博客系统只能在本地测试,而没有放到服务器上的缺憾,暗下决心要是项目本地开发成功,一定要买个服务器在上面部署。

二月伊始,无意中发现了QQ空间的阿里云“高校在家,实践计划”的活动,进而免费获取了一台6个月的ECS云服务器。后来这台服务器承载了项目的发布,也让我与后续的学习活动结下不解之缘。然而,当时的我陷入了间歇性踌躇满志,持续性混吃等死的状态,每天学习时间大大缩减,前期的准备工作举步维艰,以至于项目开发时间越来越长。好在我的坚持努力下,综合项目的背景,给它起了名字叫“悦享校园”,旨在基于大学生生活现状需求,打造可以提供综合的校园服务于一体的校园商铺平台。以“便捷、快速、优质”为目标,使大学生能愉悦的享受校园生活。项目名的确定,也算是为项目开发提供了一个开端。

高校计划

一切的改变源于三月份的网课,受疫情的影响,竟在这个时间里让儿时幻想过的 “在家学习” 变为了现实。在得知学期中开设的课程需要一个项目后,发现正好与自己现在的计划不谋而合。我一改往日学习状态,也是正式的开始了开发之旅,从需求分析到数据库设计,从后端测试到前端开发,从Maven到前后端联调,一步步的学习,更加体会到自己所了解的东西少之又少。此前项目使用JSP,页面改动的成本高,悦享校园中使用了ajax来进行前后端数据的交互,进而实现前后端分离。然而开发的日子里面对各种各样的Exception难免会想着放弃,每天除了上网课,还充满着许多未知的Bug,常让我深感到心力交瘁。因项目报错无法解决在放弃的边缘徘徊时,我常走出房门,站在院子里抬头看看星空,夜晚的宁静总能给我些许慰藉,情绪得以舒缓。人生之路多坎坷,更何况程序呢,怎么会没有错误呢?待心情平复下来,继续潜心修改代码。在此期间我把每天把写过的重点内容及一些步骤做以简单的记录,一来防止忘记,二来有问题了可以提供一些思路。就这样项目一点一点的推进着,看着课程表,我竟有些期待后面的日子。

技术选型

 

需求分析

 

数据库

 

项目概览
日常记录

六月的雨天不免总让人有些期待,它能给予被滚烫热浪包裹的城市喘息的机会。我依旧喜欢着这深邃的夜晚,它提供给了我更多静心思考的境地。项目的在ECS上的部署也算顺利,环境配置等按着步骤即可。虽然总会有一些小插曲,但最终都可以被解决掉。看着屏幕上来回切换的轮播图,我知道期待已久的日子终于来临,回顾整个历程,几多心酸,几多欢喜,而曾被我认为那些坚持不下来的日子,却也一步步的走了过来。更是深感一个优秀的产品在其面向大众时要经过数千次的锤炼,离不开那些背后团队开发者的努力,敬佩感油然而生。与此同时我又参加了阿里云的AI训练营与ECS训练营,完成了基于官方模板的改动的Spring Boot + Vue.js 的 “寻它”,学习收获了相关云知识,感叹新技术便捷同时,更多是对自己功力不足的担忧。随着期末考试临近,尚存Bug的 “悦享校园” 也随着为数不多的雨天逐渐一并隐没。

项目截图

我对夏天的记忆,大多是停留在一个字:热。仔细想来这或许是最后一个暑假了,不禁有些感慨这时光之快,而假期里连绵不断的雨天更让我别有一番滋味在心头。随着七月份阿里云高校计划半周年纪念日活动的结束,想起当初参与活动领取服务器、构建项目、开发部署这一切恍如昨日,历历在目。而新的Serverless Web云开发训练营活动则吸引了我的注意,让我在这剩余不多的假日又变得有趣起来。

云开发

已是八月初,终于到等到了开营的日子,但同时还有一件事情让我挂念,便是那台ECS服务器要到期了。虽然想到如果没有了ECS还可以用Serverless来做开发,也是一个新的尝试。但为了能方便之前项目的开发维护,遂认真复习备考,还好最终有惊无险,顺利通过了考试。也让我可以安心学习Serverless开发相关,“开箱即用,专注业务” 是我对Serverless云开发的第一印象。随着时间的推移,完成了七天的训练营课程,在此期间对Servless有了进一步的了解,其紧密的运作流程让我对项目开发有了别样的认识,又来到了喜闻乐见的项目环节。想到曾在学校接触过微信小程序开发一些内容, 结合Serverless正好可以尝试一下。可待我搭建好环境写完首页后,发现微信小程序本身涉及了云开发部分,那么应如何去对接部署项目?加之以前的学习中未涉及微信小程序连接数据库,无疑会增加学习成本,有可能将无法按时完成项目的提交。想到这里,我不得不做出终止开发的决定,转而选择新的方向。此时已经有同学提交项目,除了羡慕外更是焦急。眼看这比赛结束的日子越来越近,而我仍然没有找到合适的项目,兜兜转转,回归原点。我想起那个被遗忘在六月角落的悦享校园,如今这是最合适的选择了。

 

微信小程序开发

如果开发的过程是艰难的,那么部署之路也是多坎坷的。由于悦享校园使用Apache Tomcat 8.5 + JDK 1.8的环境,而云开发的SAE迁移方案目前只支持Tomcat7-maven-plugin+JDK1.7的环境,我不得不对项目中引入的依赖环境做出调整,经过了Exception的多次洗礼,终于配置了可以使用在云开发平台的上的pom.xml文件,但随即又现了新的问题,使用了Tomcat7-maven-plugin将无法使用 docBase,这将使项目的图片资源无法正常的获取,要舍弃就会使项目功能有一定的缺失,不舍弃项目便无法启动。我陷入两难的选择,查阅资料后发现这是tomcat7插件本身的Bug,可以通过替换对应的jar包来完成,一顿操作后,项目本地启动正常运行,但当我提交带有图片的信息时,会提示Permission denined。或许我应该提升一下权限,先使用cat  /etc/os-release 后得知系统为Ubuntu,su root后发现不知道密码,后用sudo su切换到root用户(一般不建议使用此命令,root具有系统的最高权限,误操作极容易引起系统数据丢失),待创建后需要的resources文件夹,使用chmod -R 777 /resources 使其获取权限(此命令是赋予一个文件夹最高操作权限,谨慎使用!),如此一来,本地测试便没有问题了。但项目部署到测试环境,图片又显示不出来了,看了看时间意识到再耗下去也没有结果,就此作罢,待来日再战。

//可运行的pom配置文件,按需修改
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<groupId>com.study</groupId>
	<artifactId>o2o</artifactId>
	<packaging>war</packaging>
	<version>0.0.1-SNAPSHOT</version>
	<name>o2o Maven Webapp</name>
	<url>http://maven.apache.org</url>
	<properties>
		<spring.version>4.1.4.RELEASE</spring.version>
    <applicationName>${project.artifactId}</applicationName>
	</properties>
	<dependencies>
		<dependency>
			<groupId>junit</groupId>
			<artifactId>junit</artifactId>
			<version>4.12</version>
			<scope>test</scope>
		</dependency>
		<!-- https://mvnrepository.com/artifact/ch.qos.logback/logback-classic -->
		<dependency>
			<groupId>ch.qos.logback</groupId>
			<artifactId>logback-classic</artifactId>
			<version>1.2.3</version>
			
		</dependency>
		<!-- Spring -->
		<!-- 1)包含Spring 框架基本的核心工具类。Spring 其它组件要都要使用到这个包里的类,是其它组件的基本核心 -->
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-core</artifactId>
			<version>${spring.version}</version>
		</dependency>
		<!-- 2)这个jar 文件是所有应用都要用到的,它包含访问配置文件、创建和管理bean 以及进行Inversion of Control 
			/ Dependency Injection(IoC/DI)操作相关的所有类。如果应用只需基本的IoC/DI 支持,引入spring-core.jar 
			及spring-beans.jar 文件就可以了。 -->
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-beans</artifactId>
			<version>${spring.version}</version>
		</dependency>
		<!-- 3)这个jar 文件为Spring 核心提供了大量扩展。可以找到使用Spring ApplicationContext特性时所需的全部类,JDNI 
			所需的全部类,instrumentation组件以及校验Validation 方面的相关类。 -->
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-context</artifactId>
			<version>${spring.version}</version>
		</dependency>
		<!-- 4) 这个jar 文件包含对Spring 对JDBC 数据访问进行封装的所有类。 -->
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-jdbc</artifactId>
			<version>${spring.version}</version>
		</dependency>
		<!-- 5) 为JDBC、Hibernate、JDO、JPA等提供的一致的声明式和编程式事务管理。 -->
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-tx</artifactId>
			<version>${spring.version}</version>
		</dependency>
		<!-- 6)Spring web 包含Web应用开发时,用到Spring框架时所需的核心类,包括自动载入WebApplicationContext特性的类、Struts与JSF集成类、文件上传的支持类、Filter类和大量工具辅助类。 -->
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-web</artifactId>
			<version>${spring.version}</version>
		</dependency>
		<!-- 7)包含SpringMVC框架相关的所有类。 -->
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-webmvc</artifactId>
			<version>${spring.version}</version>
		</dependency>
		<!-- 8)Spring test 对JUNIT等测试框架的简单封装 -->
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-test</artifactId>
			<version>${spring.version}</version>
			<scope>test</scope>
		</dependency>
		<!-- Servlet web -->
		<dependency>
			<groupId>javax.servlet</groupId>
			<artifactId>javax.servlet-api</artifactId>
			<version>3.1.0</version>
			<scope>provided</scope>
		</dependency>
		<!-- json解析 -->
		<dependency>
			<groupId>com.fasterxml.jackson.core</groupId>
			<artifactId>jackson-databind</artifactId>
			<version>2.8.7</version>
		</dependency>
		<!-- Map工具类 对标准java Collection的扩展 spring-core.jar需commons-collections.jar -->
		<dependency>
			<groupId>commons-collections</groupId>
			<artifactId>commons-collections</artifactId>
			<version>3.2</version>
		</dependency>
		<!-- DAO: MyBatis -->
		<dependency>
			<groupId>org.mybatis</groupId>
			<artifactId>mybatis</artifactId>
			<version>3.4.2</version>
		</dependency>
		<dependency>
			<groupId>org.mybatis</groupId>
			<artifactId>mybatis-spring</artifactId>
			<version>1.3.1</version>
		</dependency>
		<!-- 数据库 -->
		<dependency>
			<groupId>mysql</groupId>
			<artifactId>mysql-connector-java</artifactId>
			<version>5.1.49</version>
		</dependency>
		<dependency>
			<groupId>c3p0</groupId>
			<artifactId>c3p0</artifactId>
			<version>0.9.1.2</version>
		</dependency>
		<!-- 图片处理 -->
		<!-- https://mvnrepository.com/artifact/net.coobird/thumbnailator -->
		<dependency>
			<groupId>net.coobird</groupId>
			<artifactId>thumbnailator</artifactId>
			<version>0.4.8</version>
		</dependency>
		<!-- https://mvnrepository.com/artifact/com.github.penggle/kaptcha -->
		<dependency>
			<groupId>com.github.penggle</groupId>
			<artifactId>kaptcha</artifactId>
			<version>2.3.2</version>
		</dependency>
		<dependency>
			<groupId>commons-fileupload</groupId>
			<artifactId>commons-fileupload</artifactId>
			<version>1.3.2</version>
		</dependency>
		<!-- redis客户端:Jedis -->
		<dependency>
			<groupId>redis.clients</groupId>
			<artifactId>jedis</artifactId>
			<version>2.9.0</version>
		</dependency>

	</dependencies>
	<build>
		<finalName>${applicationName}</finalName>
		<plugins>
			<plugin>
				<!-- https://mvnrepository.com/artifact/org.apache.maven.plugins/maven-compiler-plugin -->
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-compiler-plugin</artifactId>
				<version>3.7.0</version>
				<configuration>
					<source>1.7</source>
					<target>1.7</target>
					<encoding>UTF-8</encoding>
				</configuration>
			</plugin>
			
			<plugin>	
  				<groupId>org.apache.tomcat.maven</groupId>
  				<artifactId>tomcat7-maven-plugin</artifactId>
  				<version>2.2</version>
				<configuration>
					<port>8000</port>
					<path>/</path>
					<uriEncoding>UTF-8</uriEncoding>
					<server>tomcat7</server>
				</configuration>
			</plugin>
		</plugins>
	</build>
</project>

 查看Linux系统信息

cat  /etc/os-release

 获得root权限,慎用!

sudo su

 文件夹权限修改,慎用!

chmod -R 777 /xxx    //xxx为你的文件夹目录

图片不能显示的问题是我寝食难安,我不断的搜寻着解决问题的方案。而更让我不知所措的是商品页的数据无法加载出来,查看cuo'w后发现竟是504,平时404,500也不足为怪,这个504是个什么问题,后来从群内大佬的聊天记录得知,项目是在内网,而数据库是外网ECS服务器上的,无法通信所以会出现这样的问题。通过SAE的日志文件中出现的Sokcet也验证了其准确性(SAE日志)。要访问就得通过EIP+NAT网关,需要注意在购买相应产品的Region问题。(详可参见部署在SAE上的应用如何访问公网)。解决了数据无法显示的问题后,又回到图片问题上,既然中央仓库没有要使用的jar包,是不是可以通过自己搭建自己的仓库来解决呢?利用Nexus搭建一个个人仓库,然后把修改好的jar包传上去,再从pom.xml中引用进来,岂不美哉?一时间,我仿佛看到了胜利的曙光。在Nexus搭建完成后,我小心翼翼的将找到替换包上传,满怀期待它的表现,我将重新配置的内容写入pom.xml中,看着控制台不断输出的信息,心想着这次一定没问题的,然而事与愿违,控制台区域充满的红色在开发工具中显得格外突出,仔细分析后发现是少几个jar包,查看本地仓库文件后发现原本四个文件夹只剩下了一个,我意识到问题所在,后来我将tomcat7插件附带的三个文件夹一并上传到Nexus,更新了配置文件,等待成功的到来,但如期而至[的Error],彻底浇灭了我的幻想。后来我看到前辈在博客中的内容,需要在原有的jar包基础上覆盖,这样看来,这一次的尝试注定是没有结果。

nexus

由于使用了朋友的二级域名,没有相应的ssl证书,打开页面时总是显示链接不安全。在发现可以使用certbot来配置免费的ssl证书后(获取免费https认证 详解certbot使用步骤),我准备试着给这个域名也配置一下,看着比赛结束日子结束倒计时逐渐逼近,我却也无可奈何。由于没有思路,图片无法显示的问题也只好先抛在一边,在配置certbot时,使用了nginx,但对于它的了解也只是在字面的,学习配置过后,一个念头从脑海闪过,或许我可以使用nginx作为图片资源服务器,从而可以脱离tomcat7插件的限制。我兴冲冲的在云开发平台中搭建好nginx,使用nginx监听到8080端口,转发请求到8000,匹配着图片地址,熟悉的创建图片目录,熟悉的chmod命令,一切都看起来多么顺其自然,本地测试过后我发现项目完美运行,看着屏幕右下方的04:04,不禁苦笑,这个数字我是不太愿意看到的。盘点当天完成的内容之后,我满意的进入了梦乡。

ngin相关(以下命令适用于Ubuntu)

启动

service nginx start

停止

service nginx stop

重启

service nginx restart

nginx.xml配置 

server{
        listen          8080;
        server_name     localhost;
		#请求匹配目录
        location /img/ {
		    #实际文件目录
            root  /resources/upload/; 
            autoindex on;
        }
        
	    location / {
            #转发请求到8000端口
            proxy_pass  http://localhost:8000/;
        }
}

在IDE中顺手打出service start nginx后执行,结果发现 nginx: unrecognized service,顿感大事不好,或许是容器冻结重置的原因,连同一起的resources文件也消失了,好在我记录了配置文件的内容,很快将环境又重新配置起来,本地测试通过后,部署到测试环境,结果又出现了让我头疼的问题,图片依旧加载不出来。是权限不足?抑或是转发错误?我全然不知,因为对Docker容器从未有过接触,出现这样的问题也是难以避免的。近来反复数次的打开项目,竟让我有些厌倦,我看着屏幕,多希望自己能进入这程序中,对问题的根源一探究竟。看着比赛即将截至的通知,我只好另辟蹊径,将相关图片处理的内容代码先删除掉,使用ECS上的nginx服务器做图片配置,如此便保证了图片的访问。经过测试后终于成功运行,但页面仍有图片缺失,仔细排查后发现,由于配置了https的缘故,要在图片路径前显式的加上“https:”,否则图片请求的路径会变为 “http”,自然是无法访问到的。项目在部署到测试环境后除了慢一些之外一切正常,接着是预发环境,我在房间来回踱步等待着项目的部署完成。忽然间看到屏幕上的字符停止了滚动,连忙上前查看一番,竟是新的错误。根据错误信息提示,所属VPC命名不匹配,但我发现在环境管理的配置中所有的信息都是正常的,一时间又陷入僵局。反复查看错误信息后发现cn-shanghai的字样莫名感到眼熟,好像在哪里见过,最后在SAE控制台的命名管理中找到了答案,将VPC手动切换后,预发环境也随即恢复了正常,我知道胜利在望。最后是线上环境的部署,此时我坐在电脑前,目不转睛地看着屏幕,生怕遗漏重要的信息。虽然之前的测试都已通过,想必也不会有什么问题了,但我仍旧有些不放心。随着部署成功的字样出现,打开自定义的域名,久违的首页,逐个功能测试后,发现除了数据加载仍较慢之外, 其他的功能也都基本正常。此时此刻我所有的情绪都融进了夏夜的凌晨里,在时光的流逝里变得悄无声息。

或许OSS是不错的选择,但当我删除代码那一刻,我已学习从过程中收获,历史的车轮滚滚碾过,不合时宜的终将没落。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值