1. 在线学习
1.1 需求分析
用户通过课程详情界面点击马上学习 进入 视频插放界面进行视频点播。
获取视频资源时进行学习资格校验,如下图:
拥有学习资格则继续播放视频,不具有学习资格则引导去购买、续期等操作。
如何判断是否拥有学习资格?
首先判断是否为试学视频,如果为试学视频则可以正常学习。
如果为非试学课程首先判断用户是否登录,如果已登录则判断是否选课,如果已经选课且没有过期可以正常学习。
详细流程如下图:
1.2 查询课程信息
在视频点播页面需要查询课程信息,课程上线后也需要访问/api/content/course/whole/{courseId}
课程预览时请求获取课程的接口为:/open/content/course/whole/{courseId}
在nginx中进行配置:
/open、/api在nginx的配置如下:(已经配置的不要重复配置)
#api
location /api/ {
proxy_pass http://gatewayserver/;
}
#openapi
location /open/content/ {
proxy_pass http://gatewayserver/content/open/;
}
location /open/media/ {
proxy_pass http://gatewayserver/media/open/;
}
下边实现/api/content/course/whole/{courseId} 获取课程发布信息接口。
进入内容管理服务api工程CoursePublishController 类,定义查询课程预览信息接口如下
/**
* 获取课程发布信息
* @param courseId
* @return
*/
@ApiOperation("获取课程发布信息")
@ResponseBody
@GetMapping("/course/whole/{courseId}")
public CoursePreviewDto getCoursePublish(@PathVariable("courseId") Long courseId) {
//查询课程发布信息
CoursePublish coursePublish = coursePublishService.getCoursePublish(courseId);
if (coursePublish == null) {
return new CoursePreviewDto();
}
//课程基本信息
CourseBaseInfoDto courseBase = new CourseBaseInfoDto();
BeanUtils.copyProperties(coursePublish, courseBase);
//课程计划
List<TeachplanDto> teachplans = JSON.parseArray(coursePublish.getTeachplan(), TeachplanDto.class);
CoursePreviewDto coursePreviewInfo = new CoursePreviewDto();
coursePreviewInfo.setCourseBase(courseBase);
coursePreviewInfo.setTeachplans(teachplans);
return coursePreviewInfo;
}
重启内容管理服务,进入学习界面查看课程计划、课程名称等信息是否显示正常
1.3 获取视频
- 需求分析
- 定义接口
package com.xuecheng.learning.api;
import com.xuecheng.base.model.RestResponse;
import com.xuecheng.learning.service.LearningService;
import com.xuecheng.learning.util.SecurityUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
/**
* 我的学习接口
*/
@Api(value = "学习过程管理接口", tags = "学习过程管理接口")
@Slf4j
@RestController
public class MyLearningController {
@Autowired
LearningService learningService;
/**
* 获取视频
* @param courseId
* @param teachplanId
* @param mediaId
* @return
*/
@ApiOperation("获取视频")
@GetMapping("/open/learn/getvideo/{courseId}/{teachplanId}/{mediaId}")
public RestResponse<String> getvideo(@PathVariable("courseId") Long courseId,@PathVariable("teachplanId") Long teachplanId, @PathVariable("mediaId") String mediaId) {
//登录用户
SecurityUtil.XcUser user = SecurityUtil.getUser();
String userId = null;
if (user != null) {
userId = user.getId();
}
//获取视频
return null;
}
}
- service接口
package com.xuecheng.learning.service;
import com.xuecheng.base.model.RestResponse;
/**
* 在线学习相关的接口
*/
public interface LearningService {
/**
* @description 获取教学视频
* @param courseId 课程id
* @param teachplanId 课程计划id
* @param mediaId 视频文件id
*/
public RestResponse<String> getVideo(String userId, Long courseId, Long teachplanId, String mediaId);
}
- 获取视频接口
package com.xuecheng.learning.feignclient;
import com.xuecheng.base.model.RestResponse;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
/**
* 媒资管理远程服务接口
*/
@FeignClient(value = "media-api",fallbackFactory = MediaServiceClientFallbackFactory.class)
@RequestMapping("/media")
public interface MediaServiceClient {
@GetMapping("/open/preview/{mediaId}")
public RestResponse<String> getPlayUrlByMediaId(@PathVariable("mediaId") String mediaId);
}
FeignClient接口的降级类
@Slf4j
@Component
public class MediaServiceClientFallbackFactory implements FallbackFactory<MediaServiceClient> {
@Override
public MediaServiceClient create(Throwable throwable) {
return new MediaServiceClient() {
@Override
public RestResponse<String> getPlayUrlByMediaId(String mediaId) {
log.error("远程调用媒资管理服务熔断异常:{}",throwable.getMessage());
return null;
}
};
}
}
- 学习资格校验
编写获取视频的接口实现方法
package com.xuecheng.learning.service.impl;
import com.xuecheng.base.model.RestResponse;
import com.xuecheng.content.model.po.CoursePublish;
import com.xuecheng.learning.feignclient.ContentServiceClient;
import com.xuecheng.learning.feignclient.MediaServiceClient;
import com.xuecheng.learning.model.dto.XcCourseTablesDto;
import com.xuecheng.learning.service.LearningService;
import com.xuecheng.learning.service.MyCourseTablesService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
/**
* 在线学习接口
*/
@Slf4j
@Service
public class LearningServiceImpl implements LearningService {
@Autowired
MyCourseTablesService myCourseTablesService;
@Autowired
ContentServiceClient contentServiceClient;
@Autowired
MediaServiceClient mediaServiceClient;
@Override
public RestResponse<String> getVideo(String userId, Long courseId, Long teachplanId, String mediaId) {
//查询课程信息
CoursePublish coursepublish = contentServiceClient.getCoursepublish(courseId);
//判断如果为null不再继续
if(coursepublish == null){
return RestResponse.validfail("课程不存在");
}
//远程调用内容管理服务根据课程计划id(teachplanId)去查询课程计划信息,如果is_preview的值为1表示支持试学
//也可以从coursepublish对象中解析出课程计划信息去判断是否支持试学
//todo:如果支持试学调用媒资服务查询视频的播放地址,返回
//用户已登录
if(StringUtils.isNotEmpty(userId)){
//获取学习资格
XcCourseTablesDto learningStatus = myCourseTablesService.getLearningStatus(userId, courseId);
//学习资格,[{"code":"702001","desc":"正常学习"},{"code":"702002","desc":"没有选课或选课后没有支付"},{"code":"702003","desc":"已过期需要申请续期或重新支付"}]
String learnStatus = learningStatus.getLearnStatus();
if("702002".equals(learnStatus)){
return RestResponse.validfail("无法学习,因为没有选课或选课后没有支付");
}else if("702003".equals(learnStatus)){
return RestResponse.validfail("已过期需要申请续期或重新支付");
}else{
//有资格学习,要返回视频的播放地址
//程调用媒资获取视频播放地址
RestResponse<String> playUrlByMediaId = mediaServiceClient.getPlayUrlByMediaId(mediaId);
return playUrlByMediaId;
}
}
//如果用户没有登录
//取出课程的收费规则
String charge = coursepublish.getCharge();
if("201000".equals(charge)){
//有资格学习,要返回视频的播放地址
//远程调用媒资获取视频播放地址
RestResponse<String> playUrlByMediaId = mediaServiceClient.getPlayUrlByMediaId(mediaId);
return playUrlByMediaId;
}
return RestResponse.validfail("课程需要购买");
}
}
- 测试
完善接口
/**
* 获取视频
* @param courseId
* @param teachplanId
* @param mediaId
* @return
*/
@ApiOperation("获取视频")
@GetMapping("/open/learn/getvideo/{courseId}/{teachplanId}/{mediaId}")
public RestResponse<String> getvideo(@PathVariable("courseId") Long courseId, @PathVariable("courseId") Long teachplanId, @PathVariable("mediaId") String mediaId) {
//登录用户
SecurityUtil.XcUser user = SecurityUtil.getUser();
String userId = null;
if (user != null) {
userId = user.getId();
}
//获取视频
return learningService.getVideo(userId, courseId, teachplanId, mediaId);
}
1.4 我的课表
1.4.1 需求分析
登录网站,点击“我的学习”进入个人中心,
个人中心首页显示我的课程表:
我的课表中显示了选课成功的免费课程、收费课程。最近学习课程显示了当前用户最近学习的课程信息。
点击继续学习进入当前学习章节的视频继续学习。
点击课程评价进入课程评价界面。
- 在nginx配置用户中心server
server {
listen 80;
server_name ucenter.51xuecheng.cn;
#charset koi8-r;
ssi on;
ssi_silent_errors on;
#access_log logs/host.access.log main;
location / {
alias D:/itcast2022/xc_edu3.0/code_1/xc-ui-pc-static-portal/ucenter/;
index index.html index.htm;
}
location /include {
proxy_pass http://127.0.0.1;
}
location /img/ {
proxy_pass http://127.0.0.1/static/img/;
}
location /api/ {
proxy_pass http://gatewayserver/;
}
}
1.4.2 定义接口
- 在MyCourseTablesController中定义我的课程表接口
/*
* 我的课程表
*/
@ApiOperation("我的课程表")
@GetMapping("/mycoursetable")
public PageResult<XcCourseTables> mycoursetable(MyCourseTableParams params) {
//登录用户
SecurityUtil.XcUser user = SecurityUtil.getUser();
if(user == null){
XueChengPlusException.cast("请登录后继续选课");
}
String userId = user.getId();
//设置当前的登录用户
params.setUserId(userId);
return myCourseTablesService.mycoursetables(params);
}
1.4.3 接口开发
- 定义service接口
/**
* @description 我的课程表
* @param params
* @return
*/
public PageResult<XcCourseTables> mycoursetables(MyCourseTableParams params);
- 实现类
/**
* 我的课程表
* @param params
* @return
*/
public PageResult<XcCourseTables> mycoursetables(MyCourseTableParams params){
//页码
long pageNo = params.getPage();
//每页记录数
long pageSize = params.getSize();
//分页条件
Page<XcCourseTables> page = new Page<>(pageNo, pageSize);
//根据用户id查询
String userId = params.getUserId();
LambdaQueryWrapper<XcCourseTables> lambdaQueryWrapper = new LambdaQueryWrapper<XcCourseTables>().eq(XcCourseTables::getUserId, userId);
//分页查询
Page<XcCourseTables> pageResult = courseTablesMapper.selectPage(page, lambdaQueryWrapper);
List<XcCourseTables> records = pageResult.getRecords();
//记录总数
long total = pageResult.getTotal();
PageResult<XcCourseTables> courseTablesResult = new PageResult<>(records, total, pageNo, pageSize);
return courseTablesResult;
}
2. 项目部署
2.1 DevOps
下边是摘自百度百科的定义:
DevOps(Development和Operations的组合词)是一组过程、方法与系统的统称,用于促进开发(应用程序/软件工程)、技术运营和质量保障(QA)部门之间的沟通、协作与整合。
它是一种重视“软件开发人员(Dev)”和“IT运维技术人员(Ops)”之间沟通合作的文化、运动或惯例。透过自动化“软件交付”和“架构变更”的流程,来使得构建、测试、发布软件能够更加地快捷、频繁和可靠。
它的出现是由于软件行业日益清晰地认识到:为了按时交付软件产品和服务,开发和运维工作必须紧密合作。
DevOps是一个工具吗?
DevOps是一个工作职位吗?
都不是。
DevOps是一种思想理念,它涵盖开发、测试、运维的整个过程。DevOps追求的目标是提高软件开发、测试、运维、运营等各部门的沟通与协作质量,DevOps强调软件开发人员与软件测试、软件运维、质量保障(QA)部门之间有效的沟通与协作,强调通过自动化的方法去管理软件变更、软件集成,使软件从构建到测试、发布更加快捷、可靠,最终按时交付软件。
2.2 CI/CD
DevOps兴起于2009年,近年来由于云计算、互联网的发展,促进了DevOps的基础设施及工具链的发展,涌现了一大批优秀的工具,这些工具包括开发、测试、运维的各各领域,例如:GitHub、Docker、Jenkins、Hudson、K8S、Ant/Maven/Gradle、Selenium、QUnit、JMeter等。下图是DevOps相关的工具集:
好的工具有利于DevOps的实施,但并不代表实施DevOps就一定需要去引入一堆工具。
问题的关键:如何解决问题,而不是具体应用工具。
CI/CD 是近年来企业有效实施DevOps的具体方案。
CI/CD 包含了一个 CI 和两个 CD,CI全称 Continuous Integration,表示持续集成,CD包含 Continuous Delivery和 Continuous Deployment,分别是持续交付和持续部署,三者具有前后依赖关系。
CI 持续集成:
持续集成倡导团队成员需要频繁的集成他们的工作,将开发分支合并到主分支,每次集成都通过自动化构建(包括编译、构建、自动化测试)来验证,从而尽快地发现集成中的错误,让产品可以快速迭代,同时还能保持高质量。
CD持续交付:
持续交付将集成后的代码部署到类生产环境(预发布),除了交付到类生产环境之外,还会执行一些集成测试、API测试。持续交付强调的是“交付”,交付给测试、产品验收,不管怎么更新,软件是随时随地可以交付的。
CD持续部署:
在持续交付的基础上由开发人员或运维人员自助式的定期向生产环境部署稳定的构建版本,持续部署的目标是代码在任何时刻都是可部署的,并可自动进入到生产环境。
2.3 DevOps实战
2.3.1 技术方案
2.3.2 准备环境
准备一台Centos7 虚拟机,安装Docker、jdk、maven,通过Docker容器安装jenkins、Docker私服软件,其它软件为学成在线项目所需要的,如下:
Mysql | 8.x | docker |
nacos | 1.4.1 | docker |
rabbitmq | 3.8.34 | docker |
redis | 6.2.7 | docker |
xxl-job-admin | 2.3.1 | docker |
minio | RELEASE.2022-09-07 | docker |
elasticsearch | 7.12.1 | docker |
kibana | 7.12.1 | docker |
gogs | 0.13.0 | docker |
nginx | 1.12.2 | docker |
在课堂资料中提供了安装以上软件的虚拟机,使用VMware导入即可使用。
2.3.3 人工部署方式
- 打包,在父工程聚合各模块
首先在父工程添加models,聚合各各模块
<modules>
<module>../xuecheng-plus-base</module>
<module>../xuecheng-plus-checkcode</module>
<module>../xuecheng-plus-gateway</module>
<module>../xuecheng-plus-auth</module>
<module>../xuecheng-plus-content</module>
<module>../xuecheng-plus-learning</module>
<module>../xuecheng-plus-media</module>
<module>../xuecheng-plus-orders</module>
<module>../xuecheng-plus-message-sdk</module>
<module>../xuecheng-plus-search</module>
<module>../xuecheng-plus-system</module>
</modules>
- 配置打包插件
使用springboot打包插件进行打包,在需要打可执行包的工程中配置spring-boot-maven-plugin插件否则报 “jar中没有主清单属性” 。
注意:在要打可执行jar包的工程中配置该插件。
<build>
<finalName>${project.artifactId}-${project.version}</finalName>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>${spring-boot.version}</version>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
- 部署到Linux
将打成的jar包拷贝到Linux,生成镜像,并创建容器。
- 编写Dockerfile文件
FROM java:8u20
MAINTAINER docker_maven docker_maven@email.com
WORKDIR /ROOT
ADD xuecheng-plus-checkcode-0.0.1-SNAPSHOT.jar xuecheng-plus-checkcode.jar
CMD ["java", "-version"]
ENTRYPOINT ["java", "-Dfile.encoding=utf-8","-jar", "xuecheng-plus-checkcode.jar"]
EXPOSE 63075
-
创建镜像
docker build -t checkcode:1.0 .
- 创建容器
docker run --name xuecheng-plus-checkcode -p 63075:63075 -idt checkcode:1.0
- 测试
### 申请验证码
POST 192.168.101.65:63075/checkcode/pic
2.3.4 自动部署
- 实战流程
1、将代码 使用Git托管
2、在jenkins创建任务,从Git拉取代码。
3、拉取代码后进行自动构建:测试、打包、部署。
首先将代码打成镜像包上传到docker私服。
自动创建容器、启动容器。
4、当有代码push到git实现自动构建。
- 提价代码到Git
- 修改pom.xml文件
在pom.xml添加docker-maven-plugin插件实现将springboot工程创建镜像, 此pom.xml添加docker-maven-plugin插件用于生成镜像。
分别修改system-api、content-api、media-api、gateway、auth、checkcode服务的pom.xml文件。
插件的坐标如下:
<dependency>
<groupId>com.spotify</groupId>
<artifactId>docker-maven-plugin</artifactId>
<version>1.2.2</version>
</dependency>
修改pom.xml文件,以xuecheng-plus-checkcode为例,如下:
<build>
<finalName>${project.artifactId}-${project.version}</finalName>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>${spring-boot.version}</version>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>com.spotify</groupId>
<artifactId>docker-maven-plugin</artifactId>
<version>1.2.2</version>
<configuration>
<!--修改imageName节点的内容,改为私有仓库地址和端口,再加上镜像id和 TAG,我们要直接传到私服-->
<!--配置最后生成的镜像名,docker images里的,我们这边取项目名:版本-->
<!--<imageName>${project.artifactId}:${project.version}</imageName>-->
<imageName>192.168.101.65:5000/${project.artifactId}:${project.version}</imageName>
<!--也可以通过以下方式定义image的tag信息。 -->
<!-- <imageTags>
<imageTag>${project.version}</imageTag>
<!–build 时强制覆盖 tag,配合 imageTags 使用–>
<forceTags>true</forceTags>
<!–build 完成后,push 指定 tag 的镜像,配合 imageTags 使用–>
<pushImageTag>true</pushImageTag>
</imageTags>-->
<baseImage>java:8u20</baseImage>
<maintainer>docker_maven docker_maven@email.com</maintainer>
<workdir>/root</workdir>
<cmd>["java", "-version"]</cmd>
<!--来指明Dockerfile文件的所在目录,如果配置了dockerDirectory则忽略baseImage,maintainer等配置-->
<!--<dockerDirectory>./</dockerDirectory>-->
<!--2375是docker的远程端口,插件生成镜像时连接docker,这里需要指定docker远程端口-->
<dockerHost>http://192.168.101.65:2375</dockerHost>
<!--入口点,project.build.finalName就是project标签下的build标签下 的filename标签内容,testDocker-->
<!--相当于启动容器后,会自动执行java -jar ...-->
<entryPoint>["java", "-Dfile.encoding=utf-8","-jar", "/root/${project.build.finalName}.jar"]</entryPoint>
<!--是否推送到docker私有仓库,旧版本插件要配置maven的settings文件。 -->
<pushImage>true</pushImage>
<registryUrl>192.168.101.65:5000</registryUrl> <!-- 这里是复制 jar 包到 docker 容器指定目录配置 -->
<resources>
<resource>
<targetPath>/root</targetPath>
<directory>${project.build.directory}</directory>
<!--把哪个文件上传到docker,相当于Dockerfile里的add app.jar /-->
<include>${project.build.finalName}.jar</include>
</resource>
</resources>
</configuration>
</plugin>
</plugins>
</build>
其中system-api服务的bootstrap.yml修改如下
server:
servlet:
context-path: /system
port: 63110
#微服务配置
spring:
application:
name: system-api
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://192.168.101.65:3306/xcplus_system?serverTimezone=UTC&userUnicode=true&useSSL=false&
username: root
password: mysql
cloud:
nacos:
server-addr: 192.168.101.65:8848
discovery:
namespace: dev166
group: xuecheng-plus-project
# 日志文件配置路径
logging:
config: classpath:log4j2-dev.xml
# swagger 文档配置
swagger:
title: "学成在线系统管理"
description: "系统管理接口"
base-package: com.xuecheng.system
enabled: true
version: 1.0.0
在system-api工程添加nacos的依赖
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
- 自动构建测试
- 部署前端门户
在虚拟机的docker中已经部署了nginx,修改nginx.conf的配置文件
#user nobody;
worker_processes 1;
#error_log logs/error.log;
#error_log logs/error.log notice;
#error_log logs/error.log info;
#pid logs/nginx.pid;
events {
worker_connections 1024;
}
http {
server_names_hash_bucket_size 64;
client_max_body_size 100M; # 设置客户端请求体最大值
client_body_buffer_size 128k; # 设置请求体缓存区大小
include mime.types;
default_type application/octet-stream;
#log_format main '$remote_addr - $remote_user [$time_local] "$request" '
# '$status $body_bytes_sent "$http_referer" '
# '"$http_user_agent" "$http_x_forwarded_for"';
#access_log logs/access.log main;
sendfile on;
#tcp_nopush on;
#keepalive_timeout 0;
keepalive_timeout 65;
#文件服务
upstream fileserver{
server 192.168.101.65:9000 weight=10;
}
#后台网关
upstream gatewayserver{
server 192.168.101.65:63010 weight=10;
}
#gzip on;
server {
listen 80;
server_name www.51xuecheng.cn localhost;
#rewrite ^(.*) https://$server_name$1 permanent;
#charset koi8-r;
ssi on;
ssi_silent_errors on;
#access_log logs/host.access.log main;
location / {
alias /etc/nginx/html/;
index index.html index.htm;
}
#api
location /api/ {
proxy_pass http://gatewayserver/;
}
#静态资源
location /static/img/ {
alias /etc/nginx/html/img/;
}
location /static/css/ {
alias /etc/nginx/html/css/;
}
location /static/js/ {
alias /etc/nginx/html/js/;
}
location /static/plugins/ {
alias /etc/nginx/html/plugins/;
add_header Access-Control-Allow-Origin http://ucenter.51xuecheng.cn;
add_header Access-Control-Allow-Credentials true;
add_header Access-Control-Allow-Methods GET;
}
location /plugins/ {
alias /etc/nginx/html/plugins/;
}
location /course/preview/learning.html {
alias /etc/nginx/html/course/learning.html;
}
location /course/search.html {
root /etc/nginx/html;
}
location /course/learning.html {
root /etc/nginx/html;
}
location /course/ {
proxy_pass http://fileserver/mediafiles/course/;
}
#openapi
location /open/content/ {
proxy_pass http://gatewayserver/content/open/;
}
location /open/media/ {
proxy_pass http://gatewayserver/media/open/;
}
#error_page 404 /404.html;
# redirect server error pages to the static page /50x.html
#
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
# proxy the PHP scripts to Apache listening on 127.0.0.1:80
#
#location ~ \.php$ {
# proxy_pass http://127.0.0.1;
#}
# pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
#
#location ~ \.php$ {
# root html;
# fastcgi_pass 127.0.0.1:9000;
# fastcgi_index index.php;
# fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name;
# include fastcgi_params;
#}
# deny access to .htaccess files, if Apache's document root
# concurs with nginx's one
#
#location ~ /\.ht {
# deny all;
#}
}
server {
listen 80;
server_name file.51xuecheng.cn;
#charset koi8-r;
ssi on;
ssi_silent_errors on;
#access_log logs/host.access.log main;
location /video {
proxy_pass http://fileserver;
}
location /mediafiles {
proxy_pass http://fileserver;
}
}
server {
listen 80;
server_name teacher.51xuecheng.cn;
#charset koi8-r;
ssi on;
ssi_silent_errors on;
#access_log logs/host.access.log main;
location / {
alias /etc/nginx/html/dist/;
index index.html index.htm;
}
#location / {
# proxy_pass http://uidevserver;
#}
location /api/ {
proxy_pass http://gatewayserver/;
}
}
server {
listen 80;
server_name ucenter.51xuecheng.cn;
#charset koi8-r;
ssi on;
ssi_silent_errors on;
#access_log logs/host.access.log main;
location / {
alias /etc/nginx/html/ucenter/;
index index.html index.htm;
}
location /include {
proxy_pass http://192.168.101.65;
}
location /img/ {
proxy_pass http://192.168.101.65/static/img/;
}
location /api/ {
proxy_pass http://gatewayserver/;
}
}
# another virtual host using mix of IP-, name-, and port-based configuration
#
#server {
# listen 8000;
# listen somename:8080;
# server_name somename alias another.alias;
# location / {
# root html;
# index index.html index.htm;
# }
#}
# HTTPS server
#
#server {
# listen 443 ssl;
# server_name localhost;
# ssl_certificate cert.pem;
# ssl_certificate_key cert.key;
# ssl_session_cache shared:SSL:1m;
# ssl_session_timeout 5m;
# ssl_ciphers HIGH:!aNULL:!MD5;
# ssl_prefer_server_ciphers on;
# location / {
# root html;
# index index.html index.htm;
# }
#}
}
将前端门户的静态页面拷贝到 /data/soft/nginx/xuecheng_portal_static
启动nginx容器:
docker start nginx
修改本机hosts文件:
192.168.101.65 www.51xuecheng.cn 51xuecheng.cn ucenter.51xuecheng.cn teacher.51xuecheng.cn file.51xuecheng.cn
将本机的nginx服务停掉,访问www.51xuecheng.cn。
- 部署机构端前端
将机构端的前端工程打包,运行yarn build
打包成功在工程目录生成dist目录
将此目录的内容拷贝到虚拟机的/data/soft/nginx/xuecheng_portal_static/dist
- 配置触发器
当向gogs提交代码时进行自动构建
在gogs配置钩子
推送地址设置jenkins的接口:
http://192.168.101.65:8888/gogs-webhook/?job=jenkins_02
配置好可以测试一下:
测试后观察jenkina是否重新构建任务。
提交代码测试:
修改代码提交到gogs,观察jenkins是否自动构建任务