华为云PaaS平台微服务治理4学成在线项目接入CSE

58 篇文章 1 订阅
14 篇文章 1 订阅

4学成在线项目接入CSE

学成在线项目是黑马程序员JavaEE大型综合实战项目,本章节实现学成在线项目接入CSE,本项目采用
SpringCloud框架开发,本章节系统讲解SpringCloud项目接入CSE的开发步骤。

4.1项目介绍

4.1.1技术架构
学成在线采用当前流行的前后端分离架构开发,前端采用vue.js构建,服务端采用Spring Cloud微服务架构,系统分为用户层、CDN、负载均衡、前端UI、微服务层、数据层、接口层及DevOps等部分组成,技术架构图如下:
在这里插入图片描述
4.1.2业务流程
本次接入CSE以学成在线项目中“在线播放视频”业务流程为案例进行讲解,业务流程业务如下:
1、进入门户
在这里插入图片描述
2、搜索课程
点击“课程”进入课程搜索页面,搜索课程
在这里插入图片描述
3、进入课程学习页面
点击进入课程详情页面,点击“马上学习”
在这里插入图片描述
在这里插入图片描述
4.1.3项目部署
1、安装MySQL、导入“资料”–》“学成在线”–》MySQL目录下的脚本。
2、安装MongoDB,导入“资料”–》“学成在线”–》mongodb目录下的脚本。
3、安装ElasticSearch,参考“资料”–》“学成在线”–》elasticsearch下的脚本使用postman导入初始化数据。 4、启动以下微服务
xc-govern-center:注册中心xc-govern-gateway: 网关
xc-service-portalview:数据视图服务

xc-service-search: 搜索服务xc-service-learning: 学习服务5、前端工程
解压“资料”–》“学成在线”–》xc-ui-pc-learning.zip,此为学习中心前端工程解压“资料”–》“学成在线”–》xc-ui-pc-portal.zip,此为搜索前端工程
使用webstorm分别打开两个前端工程。
分别在两个目录下运行npm install或cnpm install
运行 npm run dev 启动前端工程。

解压门户工程,“资料”–》“学成在线”–》xc-ui-pc-static-portal.zip 解压静态资源,“资料”–》“学成在线”–》static.zip
解压视频资源,“资料”–》“学成在线”–》video.zip
安装nginx,并参考“资料”–》“学成在线”–》nginx.conf配置nginx.conf 配置nginx.conf注意以下虚拟主机的配置:
90端口为视频播放
91端口为静态资源xuechengcloud.java.itcast.cn为门户xcucentercloud.java.itcast.cn 为学习中心

启动Nginx。

运行工程,需要在hosts文件中配置域名
127.0.0.1 xuechengcloud.java.itcast.cn 127.0.0.1 xcucentercloud.java.itcast.cn 127.0.0.1 xcsystemcloud.java.itcast.cn 127.0.0.1 xcteachercloud.java.itcast.cn 127.0.0.1 xcimgcloud.java.itcast.cn
127.0.0.1 xcvideocloud.java.itcast.cn
浏览:http://xuechengcloud.java.itcast.cn

4.1.4微服务技术栈
在“在线播放视频”业务流程中包括数据视图服务、在线学习服务、搜索等微服务,交互关系图如下:
在这里插入图片描述
交互流程如下:
1、前端通过网关调用xc-service-search搜索课程
2、前端通过网关调用xc-service-learning获取学习权限,拥有学习权限则得到视频播放地址 3、xc-service-learning校验学习权限,有权限则请求xc-service-portalview查询视频播放地址 4、学习服务、数据视图服务、搜索服务向Eureka服务注册中心上报微服务信息。

微服务基于Spring Boot构建,技术栈如下:
SpringBoot、SpringCloud、Swagger、Spring Data Mongodb、MyBatis、Spring Data Jpa、 com.alibaba.druid、Ribbon、Feign Client、Hystrix

4.1.5原始代码结构
项目接入CSE需要修改项目代码,在修改代码之前我们先了解一下原始接口的代码结构。
4.1.5.1查询课程视图接口
学习中心前端请求搜索服务查询课程信息接口
1、接口定义
项目统一在xc-service-api工程中定义接口,在搜索服务包下定义此接口。

@Api(value = "课程搜索",description = "课程搜索") public interface EsCourseControllerApi {
final String API_PRE = "/search/course";

@GetMapping(API_PRE+"/list/{page}/{size}") @ApiOperation("课程搜索")
public Map list(@PathVariable("page") int page,
@PathVariable("size") int size,
CourseSearchParam courseSearchParam) throws IOException;

@GetMapping(value=API_PRE+"/getall/{id}") @ApiOperation("根据id查询课程信息")
public Map<String,CoursePub> getall(@PathVariable("id") String id) throws IOException;
...
}

2、接口实现
在xc-service-search工程定义接口实现。

@RestController
public class EsCourseController implements EsCourseControllerApi { @Autowired
EsCourseService esCourseService;

@Override
public Map list(@PathVariable("page") int page, @PathVariable("size") int size, CourseSearchParam courseSearchParam) throws IOException {
String result = esCourseService.list(page,size,courseSearchParam); return JSON.parseObject(result, Map.class);
}

@Override
public Map<String, CoursePub> getall(@PathVariable("id") String id) throws IOException { return esCourseService.getall(id);
}
...
}

4.1.5.2获取学习地址接口
学习服务提供获取学习地址接口,学习中心前端请求学习服务获取获取学习地址。
1、接口定义
在xc-service-api工程下的学习服务包下定义此接口。

@RequestMapping("/learning")
@Api(value = "录播课程学习管理",description = "录播课程学习管理") public interface CourseLearningControllerApi {

@GetMapping("/getmedia/{courseId}/{teachplanId}") @ApiOperation("获取课程学习地址")
public GetMediaResult getmedia(@PathVariable String courseId,@PathVariable String teachplanId);
...
}

2、接口实现

@RestController
public class CourseLearningController extends BaseController implements CourseLearningControllerApi {
@Autowired
LearningService learningService;

@Override
public GetMediaResult getmedia(@PathVariable String courseId, @PathVariable String teachplanId) {
//获取课程学习地址
GetMediaResult media = learningService.getMedia(courseId, teachplanId); return media;
}
...
}

在learningService采用远程调用,这里使用SpringCloud提供的FeignClient,在学习服务中定义FeignClient:

@FeignClient(value = XcServiceList.XC_SERVICE_PORTALVIEW)
public interface PortalViewClient extends ViewCourseControllerApi {

}

learningService的getMedia方法代码如下:

//获取课程学习地址
public GetMediaResult getMedia(String courseId, String teachplanId) {
//校验学生的学习权限...

String mediaFileId = null;
//远程调用视图服务获取课程媒资信息
ViewCourseMedia viewCourseMedia = portalViewClient.findMediaById(teachplanId); 
if (viewCourseMedia == null) {
ExceptionCast.cast(LearningCode.LEARNING_GETMEDIA_ERROR);
}
//视频播放地址
String mediaUrl = viewCourseMedia.getMediaUrl(); if (StringUtils.isEmpty(mediaUrl)) {
ExceptionCast.cast(LearningCode.LEARNING_GETMEDIA_NOTFOUND);
}
//响应结果对象
GetMediaResult getMediaResult = new GetMediaResult(CommonCode.SUCCESS, mediaUrl);

return getMediaResult;
}

4.1.5.3获取视频播放地址
数据视图服务提供获取视频播放地址接口,学习服务在验证学生有学习权限后请求数据视图服务获取视频播放地 址。
1、接口定义

@Api(value = "课程数据视图服务",description = "门户课程数据视图管理接口") 
public interface ViewCourseControllerApi {
final String API_PRE = "/portalview/course";

@GetMapping(API_PRE+"/getmedia/{id}") 
@ApiOperation("通过教学计划id查询课程媒资视图")
public ViewCourseMedia findMediaById(@PathVariable("id") String id) ;
...
}

2、接口实现


@RestController
public class ViewCourseController implements ViewCourseControllerApi{
 @Override
public ViewCourseMedia findMediaById(@PathVariable("id") String id) {
 ViewCourseMedia viewCourseMedia = viewCourseService.findMediaById(id); 
 return viewCourseMedia;
}
...
}

4.2SpringCloud项目接入CSE

本章节讲解SpringCloud项目(学成在线)接入CSE的步骤和方法,以接口为单元进行接入。

4.2.1查询课程视图接口
4.2.1.1引入依赖
接入CSE平台需要在服务提供方及消费方引入 cse-solution-service-engine依赖,为了控制依赖版本在父工程进行依赖管理如下:


<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.huawei.paas.cse</groupId>
<artifactId>cse‐dependency</artifactId>
<version>2.3.20</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>

完整的父工程pom.xml如下:

<?xml version="1.0" encoding="UTF‐8"?>
<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/xsd/maven‐
4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring‐boot‐starter‐parent</artifactId>
<version>1.5.9.RELEASE</version>
</parent>
<groupId>com.xuecheng</groupId>
<artifactId>xc‐framework‐parent</artifactId>
<packaging>pom</packaging>
<version>1.0‐SNAPSHOT</version>
<properties>
<java.version>1.8</java.version>
<tomcat.version>8.5.28</tomcat.version>
<spring‐boot.version>1.5.9.RELEASE</spring‐boot.version>
<springframework.version>4.3.13.RELEASE</springframework.version>
<mybatis‐spring‐boot.version>1.3.1</mybatis‐spring‐boot.version>
<mybatis.version>3.4.5</mybatis.version>
<druid.version>1.1.6</druid.version>
<mysql‐connector‐java.version>5.1.45</mysql‐connector‐java.version>



<commons‐io.version>2.6</commons‐io.version>
<org.apache.commons.io.version>1.3.2</org.apache.commons.io.version>
<commons‐fileupload.version>1.3.3</commons‐fileupload.version>
<commons‐codec.version>1.10</commons‐codec.version>
<commons‐lang3.version>3.6</commons‐lang3.version>






<okhttp.version>3.9.1</okhttp.version>
<feign‐okhttp.version>8.18.0</feign‐okhttp.version>
<lombok.version>1.16.16</lombok.version>
<springfox‐swagger.version>2.7.0</springfox‐swagger.version>
<fastjson.version>1.2.30</fastjson.version>
<fastdfs‐client‐java.version>1.27.0.0</fastdfs‐client‐java.version>
<mysql‐connector‐java.version>5.1.40</mysql‐connector‐java.version>
<elasticsearch.version>6.2.1</elasticsearch.version>
<guava.version>24.0‐jre</guava.version>
<cse.version>2.3.30</cse.version>
</properties>
<!‐‐test‐‐>
<dependencyManagement>
<dependencies>
<!‐‐<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring‐cloud‐dependencies</artifactId>
<version>Dalston.SR5</version>
<type>pom</type>
<scope>import</scope>
</dependency>‐‐>
<dependency>
<groupId>com.huawei.paas.cse</groupId>
<artifactId>cse‐dependency</artifactId>
<version>${cse.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
...

在xc-service-search工程添加依赖:


<dependency>
<groupId>com.huawei.paas.cse</groupId>
<artifactId>cse‐solution‐service‐engine</artifactId>
<exclusions>
<exclusion>
<groupId>org.slf4j</groupId>
<artifactId>slf4j‐log4j12</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring‐boot‐starter</artifactId>
</dependency>
<dependency>
<groupId>org.apache.servicecomb</groupId>
<artifactId>spring‐boot‐starter‐provider</artifactId>
</dependency>

4.2.1.2屏蔽本项目Swagger
serviceComb提供Swagger方式生成接口契约,为防止本项目生成Swagger契约与ServiceComb冲突现将本项目的xc-service-api工程中的config/Swagger2Configuration.java类上的注解屏蔽:


//@Configuration
//@EnableSwagger2
public class Swagger2Configuration {
...

4.2.1.3接口定义
修改xc-service-course工程的com.xuecheng.search.web.controller.EsCourseController 针对query参数,ServiceComb推荐使用基本类型,课程搜索列表接口修改如下:


public Map<String,String> list(@PathVariable("page") int page, @PathVariable("size") int size,
@RequestParam("keyword") String keyword, @RequestParam("mt") String mt, @RequestParam("st") String st,
@RequestParam("grade") String grade) throws IOException;

接口实现代码如下:
屏蔽@RestController注解

//@RestController @RequestMapping("/search/course")
@RestSchema(schemaId = XcServiceList.XC_SERVICE_SEARCH)
public class EsCourseController implements EsCourseControllerApi {

@Autowired
EsCourseService esCourseService;

@GetMapping(value="/list/{page}/{size}",produces="application/json;charset=UTF‐8") @Override
public Map<String,String> list(@PathVariable("page") int page, @PathVariable("size") int size,
@RequestParam("keyword") String keyword, @RequestParam("mt") String mt, @RequestParam("st") String st, @RequestParam("grade") String grade
) throws IOException { CourseSearchParam courseSearchParam = new CourseSearchParam(); courseSearchParam.setKeyword(keyword); courseSearchParam.setSt(st);
courseSearchParam.setMt(mt); courseSearchParam.setGrade(grade);
String result = esCourseService.list(page,size,courseSearchParam); return JSON.parseObject(result, Map.class);
}

@GetMapping(value="/getbase/{ids}") @Override
public Map<String,CourseInfo> getbase(@PathVariable("ids") String ids) throws IOException { return esCourseService.getbase(ids);
}

@GetMapping(value="/getall/{id}") @Override
public Map<String, CoursePub> getall(@PathVariable("id") String id) throws IOException { return esCourseService.getall(id);
}

}

4.2.1.4服务描述配置
在src/main/resources配置microservice.yaml:


APPLICATION_ID: xc‐edu‐cloud1.0 service_description:
name: xc‐service‐search version: 1.0.0 properties:
allowCrossApp: false
cse:
service:
registry:
address: https://cse.cn‐north‐1.myhuaweicloud.com instance:
watch: false credentials:
accessKey: CMPEUCGEDINQKGWBGHVB
secretKey: HEYSZL5zTw6HLfPEOxzGnWpbzLwHWAylUc99vMtd akskCustomCipher: default
rest:
address: 0.0.0.0:40100

4.2.1.5定义服务启动入口
删除:
@EnableDiscoveryClient @EnableFeignClients
添加:
@EnableServiceComb


@EnableServiceComb @SpringBootApplication
public class SearchApplication {

public static void main(String[] args) throws Exception { 
SpringApplication.run(SearchApplication.class, args);
}

}

4.2.1.6启动服务
启动搜索服务成功。
启动服务后,登录云平台:微服务引擎CSE–>微服务管理—>服务目录,查看搜索服务已经向公有云注册中心注册成功,并且查看接口契约是否正确。
在这里插入图片描述
接口契约:
在这里插入图片描述
浏览器输入搜索地址进行测试:
在这里插入图片描述
4.2.2获取视频播放地址接口
由于xc-service-learning要调用xc-service-portalview服务的获取视频播放地址接口,所以先改造此接口。参考“查询课程视图接口”修改xc-service-portalview的获取视频播放地址接口
4.2.2.1屏蔽eureka
1、屏蔽spring-cloud-starter-eureka依赖
在这里插入图片描述
2、屏蔽spring-cloud-starter-eureka配置
在这里插入图片描述
4.2.2.2添加依赖
向xc-service-portalview的pom.xml中添加如下依赖:


<dependency>
<groupId>com.huawei.paas.cse</groupId>
<artifactId>cse‐solution‐service‐engine</artifactId>
<exclusions>
<exclusion>
<groupId>org.slf4j</groupId>
<artifactId>slf4j‐log4j12</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring‐boot‐starter</artifactId>
</dependency>
<dependency>
<groupId>org.apache.servicecomb</groupId>
<artifactId>spring‐boot‐starter‐provider</artifactId>
</dependency>

4.2.2.3接口定义
参考“查询课程视图接口”修改接口

//@RestController
@RequestMapping("/portalview/course")
@RestSchema(schemaId = XcServiceList.XC_SERVICE_PORTALVIEW)
public class ViewCourseController implements ViewCourseControllerApi{

@Autowired
ViewCourseService viewCourseService;

@GetMapping(API_PRE+"/get/{id}") @Override
public ViewCourse findById(@PathVariable("id") String id) {
 ViewCourse viewCourse = viewCourseService.findCourseById(id);
  return viewCourse;
}
@GetMapping(API_PRE+"/getmedia/{id}")
@Override
public ViewCourseMedia findMediaById(@PathVariable("id") String id) { ViewCourseMedia viewCourseMedia = viewCourseService.findMediaById(id); return viewCourseMedia;
}
}

4.2.2.4服务描述配置
参考 “查询课程视图接口”配置microservice.yaml


APPLICATION_ID: xc‐edu‐cloud1.0 service_description:
name: xc‐service‐portalview version: 1.0.0
properties:
allowCrossApp: false
cse:
service:
registry:
address: https://cse.cn‐north‐1.myhuaweicloud.com

instance:
watch: false credentials:
accessKey: CMPEUCGEDINQKGWBGHVB
secretKey: HEYSZL5zTw6HLfPEOxzGnWpbzLwHWAylUc99vMtd akskCustomCipher: default
rest:
address: 0.0.0.0:40200

4.2.2.5定义服务启动入口
删除:
@EnableDiscoveryClient @EnableFeignClients
添 加 : @EnableServiceComb 代码如下:


//@EnableDiscoveryClient @EnableServiceComb @SpringBootApplication(exclude=
{DataSourceAutoConfiguration.class,HibernateJpaAutoConfiguration.class})
 public class PortalviewApplication {
public static void main(String[] args) throws Exception { 
SpringApplication.run(PortalviewApplication.class, args);
}
}

4.2.2.6启动服务
启动服务,登录云平台查看服务目录及接口契约:
在这里插入图片描述

4.2.3获取学习地址接口

4.2.3.1需求分析
获取学习地址接口的功能内容如下:
1、接收到前端请求校验学生的学习权限。
2、如果具有学习权限则远程调用“数据视图服务”获取视频播放地址
3、将视频播放地址返回给前端。
本接口改造除了参考“查询课程视图接口”修改接口定义之外,还必须将原有的FeignClient改为ServiceComb的远程 调用方式,本项目使用ServiceComb提供的透明RPC方式实现远程调用。
4.2.3.2远程调用接口定义
在xc-service-api工程定义xc-service-portalview接口门面,方便其它服务引用接口并调用。
1、在xc-service-api工程添加依赖


<dependency>
<groupId>org.apache.servicecomb</groupId>
<artifactId>spring‐boot‐starter‐provider</artifactId>
</dependency>

2、在portalview目录下定义PortalViewApiFacade接口门面
使用serviceComb提供的@RpcReference 注解,指定微服务名称及schemaId。


@Component @Getter
public class PortalViewApiFacade {

@RpcReference(microserviceName= XcServiceList.XC_SERVICE_PORTALVIEW, schemaId= XcServiceList.XC_SERVICE_PORTALVIEW)
ViewCourseControllerApi viewCourseControllerApi;

}

4.2.3.3添加依赖
向xc-service-learning的pom.xml中添加如下依赖:

<dependency>
<groupId>com.huawei.paas.cse</groupId>
<artifactId>cse‐solution‐service‐engine</artifactId>
<exclusions>
<exclusion>
<groupId>org.slf4j</groupId>
<artifactId>slf4j‐log4j12</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>

<artifactId>spring‐boot‐starter</artifactId>
</dependency>
<dependency>
<groupId>org.apache.servicecomb</groupId>
<artifactId>spring‐boot‐starter‐provider</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring‐jdbc</artifactId>
<scope>compile</scope>
</dependency>

4.2.3.4接口定义


//@RestController @RequestMapping("/learning")
@RestSchema(schemaId = XcServiceList.XC_SERVICE_LEARNING)
public class CourseLearningController extends BaseController implements CourseLearningControllerApi {

@Autowired
LearningService learningService;

@GetMapping("/getmedia/{courseId}/{teachplanId}") @Override
public GetMediaResult getmedia(@PathVariable String courseId, @PathVariable String teachplanId) {
//获取课程学习地址
GetMediaResult media = learningService.getMedia(courseId, teachplanId); return media;
}
...

learningService的getMedia方法修改如下:
注入PortalViewApiFacade。
代码如下:

@Service
public class LearningService {
private static final Logger LOGGER = LoggerFactory.getLogger(LearningService.class);

//	@Autowired
PortalViewClient portalViewClient;
//	@Autowired
CourseClient courseClient;

@Autowired
PortalViewApiFacade portalViewApiFacade; 
@Autowired
XcLearningCourseRepository xcLearningCourseRepository;

//获取课程学习地址
public GetMediaResult getMedia(String courseId, String teachplanId) {
//校验学生的学习权限...
String mediaFileId = null;
//远程调用视图服务获取课程媒资信息
ViewCourseMedia viewCourseMedia = portalViewClient.findMediaById(teachplanId);
ViewCourseMedia viewCourseMedia =
portalViewApiFacade.getViewCourseControllerApi().findMediaById(teachplanId);
if (viewCourseMedia == null) { ExceptionCast.cast(LearningCode.LEARNING_GETMEDIA_ERROR);
}
//视频播放地址
String mediaUrl = viewCourseMedia.getMediaUrl(); if (StringUtils.isEmpty(mediaUrl)) {
ExceptionCast.cast(LearningCode.LEARNING_GETMEDIA_NOTFOUND);
}
//响应结果对象
GetMediaResult getMediaResult = new GetMediaResult(CommonCode.SUCCESS, mediaUrl);

return getMediaResult;
}

4.2.3.5服务描述配置
参考前边章节,略。
4.2.3.6定义服务启动入口
参考前边章节,略。
4.2.3.7测试
启动服务观察云平台服务目录:
在这里插入图片描述
在浏览器请求:
http://localhost:40600/learning/getmedia/402885816243d2dd016243f24c030002/8a7e867a6459d24c01645 9e7cac90002
在这里插入图片描述
4.2.4网关
4.2.4.1Edge Service
在SpringCloud中Zuul作为网关提供路由、过虑等功能。在ServiceComb中Edge Service提供JAVA网关服务。 Edge Service作为整个微服务系统对外的接口,向最终用户提供服务,接收RESTful请求,转发给内部微服务。
Edge Service以开发框架的形式提供,开发者可以非常简单的搭建一个Edge Service服务,通过简单的配置就可以定义路由转发规则。同时Edge Service支持强大的扩展能力,服务映射、请求解析、加密解密、鉴权等逻辑都可以通过扩展实现。
4.2.4.2新建Edge Service工程
创建Spring Boot工程,创建包:com.xuecheng.govern.gateway
引入如下依赖:


<dependency>
<groupId>com.huawei.paas.cse</groupId>
<artifactId>cse‐solution‐service‐engine</artifactId>
<exclusions>
<exclusion>
<groupId>org.slf4j</groupId>
<artifactId>slf4j‐log4j12</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate‐validator</artifactId>
</dependency>
<dependency>
<groupId>org.apache.servicecomb</groupId>
<artifactId>spring‐boot‐starter‐provider</artifactId>
</dependency>
<dependency>
<groupId>org.apache.servicecomb</groupId>
<artifactId>edge‐core</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring‐boot‐starter</artifactId>
</dependency>

完整的pom.xml如下:

<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/xsd/maven‐ 4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<artifactId>xc‐framework‐parent</artifactId>
<groupId>com.xuecheng</groupId>
<version>1.0‐SNAPSHOT</version>
<relativePath>../xc‐framework‐parent/pom.xml</relativePath>
</parent>
<artifactId>xc‐govern‐edgeService</artifactId>

<properties>
<project.build.sourceEncoding>UTF‐8</project.build.sourceEncoding>
<java.version>1.8</java.version>
</properties>

<dependencies>
<dependency>
<groupId>com.huawei.paas.cse</groupId>
<artifactId>cse‐solution‐service‐engine</artifactId>
<exclusions>
<exclusion>
<groupId>org.slf4j</groupId>
<artifactId>slf4j‐log4j12</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate‐validator</artifactId>
</dependency>
<dependency>
<groupId>org.apache.servicecomb</groupId>
<artifactId>spring‐boot‐starter‐provider</artifactId>
</dependency>
<dependency>
<groupId>org.apache.servicecomb</groupId>
<artifactId>edge‐core</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring‐boot‐starter</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring‐boot‐maven‐plugin</artifactId>
</plugin>
</plugins>
</build>
</project>

4.2.4.3服务描述配置
网关也相当与一个微服务,最终会向服务中心注册,服务描述配置如下:
在src/main/resource下配置application.yml,内容如下:


spring:
application:
name: xc‐edu‐edgeService server:
port: 50201 # 应用名称
APPLICATION_ID: xc‐edu‐cloud1.0 # 微服务名称和版本号service_description:
name: ${spring.application.name} version: 1.0.0
# 服务中心和配置中心的地址
cse:
service:
registry:
address: https://cse.cn‐north‐1.myhuaweicloud.com instance:
watch: false config:
client:
serverUri: https://cse.cn‐north‐1.myhuaweicloud.com refreshMode: 1
refresh_interval: 15000
# 对外发布的地址,端口号使用server.port rest:
address: 0.0.0.0:${server.port} # AK/SK认证信息,需要修改为自己的AK/SK
credentials:
accessKey: 9AKR38RXJG48XMDDIUUA
secretKey: 2MEIV4VhNzRausA3tLOsN1s7nWw66SSp9hVXBJrl akskCustomCipher: default

4.2.4.4启动类
定义启动类:


@SpringBootApplication @EnableServiceComb
public class EdgeApplication {
public static void main(String[] args) throws Exception {
 SpringApplication.run(EdgeApplication.class, args);
}
}

启动EdgeService工程,观察服务注册中心是否注册成功
在这里插入图片描述
4.2.4.5配置路由
网关的一个作用就是路由,在application.yml中配置路由,如下:


cse:
# 路由配置
http:
dispatcher:
edge:
default:
enabled: true
 prefix: api with
 Version: false
prefixSegmentCount: 2 url:
enabled: true mappings:
xc‐service‐search: prefixSegmentCount: 2 
path: "/openapi/search/.*" withVersion: false
microserviceName: xc‐service‐search
#	versionRule: 1.0.0‐2.0.0

说明:
上边的路由配置包括两部分,一部分为默认路由,一部分是根据具体url配置的路由。
1、默认路由:


edge:
default:
 enabled: true
  prefix: api
withVersion: false 
prefixSegmentCount: 2

默认路由是根据 “/prefix/微服务名称/来匹配” 请求url,如果withVersion设置为true则根据
“/prefix/微服务名称/版本号/
" 来匹配请求。
根据上边的配置举例:请求/api/xc-service-search/search/course/list/1/2 网关将请求转发到xc-service-search微服务,请求该微服务的“/search/course/list/1/2 ” URL。
prefixSegmentCount表示前缀段的个数,由于使用“/prefix/微服务名称 ”来匹配请求url所以设置为2。

启动Edge Service服务。
请 求 :http://localhost:50201/api/xc-service-search/search/course/list/1/2 通过Edge Service 请求搜索服务。

2、根据具体url配置的路由

url:
enabled: true mappings:
xc‐service‐search: #其中一个mapping名称,所有的mapping名称不允许重复
prefixSegmentCount: 2 path: "/openapi/search/.*" withVersion: false
microserviceName: xc‐service‐search #versionRule: 1.0.0‐2.0.0

请求 "/openapi/search/"将转发到微服务xc-service-search。microserviceName:微服务名称
versionRule:版本匹配规则,常用于灰度发布,上边versionRule: 1.0.0-2.0.0表示该mapping只用于1.0.0到2.0.0
版本。
启动Edge Service服务。
请 求 :http://localhost:50201/openapi/service/search/course/list/1/2 通过Edge Service 请求搜索服务。

4.2.4.6过虑器
通过过虑器可以校验请求的合法性,Edge Service提供过虑器定义方式。定义过虑器如下:

package com.xuecheng.govern.gateway.filter;

import org.apache.commons.lang3.StringUtils;
import org.apache.servicecomb.common.rest.filter.HttpServerFilter; import org.apache.servicecomb.core.Invocation;
import org.apache.servicecomb.foundation.vertx.http.HttpServletRequestEx; import org.apache.servicecomb.provider.springmvc.reference.RestTemplateBuilder; import org.apache.servicecomb.swagger.invocation.Response;
import org.apache.servicecomb.swagger.invocation.exception.InvocationException; import org.springframework.web.client.RestTemplate;

import javax.ws.rs.core.Response.Status; import java.util.Arrays;
import java.util.HashSet; import java.util.Set;

import static org.springframework.http.HttpHeaders.AUTHORIZATION; public class AuthenticationFilter implements HttpServerFilter {
private final RestTemplate template = RestTemplateBuilder.create();

private static final Set<String> NOT_REQUIRED_VERIFICATION_SERVICE_NAMES = new HashSet<>( Arrays.asList("xc‐service‐search", "xc‐service‐portalview", "xc‐service‐learning"));

@Override
public int getOrder() { return 0;
}

@Override
public Response afterReceiveRequest(Invocation invocation, HttpServletRequestEx httpServletRequestEx) {
if (isInvocationNeedValidate(invocation.getMicroserviceName())) { String token = httpServletRequestEx.getHeader(AUTHORIZATION); if (StringUtils.isNotEmpty(token)) {
//校验token...

} else {
return Response.failResp(
new InvocationException(Status.UNAUTHORIZED, "authentication failed, missing AUTHORIZATION header"));
}
}
return null;
}
private boolean isInvocationNeedValidate(String serviceName) {
for (String service_name : NOT_REQUIRED_VERIFICATION_SERVICE_NAMES) { if (serviceName.startsWith(service_name)) {
return false;
}
}
return true;
}
}

配置过虑器:
过虑器配置采用Java SPI(Service Provider Interfaces)的方式来配置,Java SPI是通过java.util.ServiceLoader实例化META-INF/services下定义的接口类(和Spring的配置类似)配置如下:
在src/main/resource下定义META-INF/services目录。
由于上边定义的过虑器实现了HttpServerFilter接口,在META-INF/services目录下定义文件,文件名称为
HttpServerFilter的全限定名,如下:
在这里插入图片描述
文件内容是上边定义的过虑器的全限定名,如下:


com.xuecheng.govern.gateway.filter.AuthenticationFilter

重新启动Edge Service工程,测试。

4.2.5集成测试
启动portalview、learning、search、edge Service服务,测试整个在线学习流程,下图集成测试结果,可以正常获取视频地址并在前端播放。
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值