当前位置: 首页 > news >正文

黑马头条-环境搭建、SpringCloud

一、项目介绍

1. 项目背景介绍

项目概述

类似于今日头条,是一个新闻资讯类项目。

随着智能手机的普及,人们更加习惯于通过手机来看新闻。由于生活节奏的加快,很多人只能利用碎片时间来获取信息,因此,对于移动资讯客户端的需求也越来越高。黑马头条项目正是在这样背景下开发出来。黑马头条项目采用当下火热的微服务+大数据技术架构实现。本项目主要着手于获取最新最热新闻资讯,通过大数据分析用户喜好精确推送咨询新闻。

业务说明

项目术语

2. 技术栈说明

基础层

服务层

3. 课程概述

收获

项目课程大纲

二、nacos

1. 服务器环境准备

前提条件:安装VWware

①解压课前资料提供的虚拟机镜像,放到你喜欢的位置

②打开VWware,点击“打开虚拟机”,选择CentosOS7-hmtt.vmx文件

③修改虚拟网络配置,子网IP改为192.168.200.0

④修改系统的网络适配器

⑤开启虚拟机,使用MobaXterm连接虚拟机

用户名:root  密码:itcast

2. nacos安装

①docker拉取镜像

docker pull nacos/nacos-server:1.2.0

②创建容器

docker run --env MODE=standalone --name nacos --restart=always -d -p 8848:8848 nacos/nacos-server:1.2.0
  • MODE=standalone:单机版
  • --restart=always:开机启动
  • -p 8848:8848:映射端口
  • -d:创建一个守护式容器在后台运行

③访问地址:http://192.168.200.130:8848/nacos

三、初始工程搭建

1. 环境准备

项目依赖环境:

  • JDK 1.8
  • Intellij Idea
  • maven-3.6.1
  • Git

步骤:

①把课前资料的heima-leadnews.zip拷贝解压到一个不带空格和中文的目录下,使用idea打开

如果识别不出来是SpringBoot工程,打开一个pom.xml文件,右键 > add as maven project

②把pom.xml里报错的信息改成如下

③把Encoding改为UTF-8

④修改maven仓库为课前资料里提供的MAVEN仓库

2. 项目结构

common模块:主要定义了一些全局异常类

feign-api模块:主要定义了远程调用接口

gateway模块:管理网关微服务

model模块:实体类

service模块:微服务工程

test模块:项目中常用的测试

utils模块:项目中常用的工具类

四、登录

1. 需求分析

用户点击开始使用:登录后的用户权限较大,可以查看,也可以操作(点赞、关注、评论)

用户点击不登录,先看看:游客只有查看的权限

2. 表结构分析

关于app端用户相关的内容较多,可以单独设置一个库leadnews_user

①启动MySQL服务,连接数据库,执行课前资料里提供的SQL脚本

②user表(放到model包下的user.pojos包)

package com.heima.model.user.pojos;import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;import java.io.Serializable;
import java.util.Date;/*** <p>* APP用户信息表* </p>** @author itheima*/
@Data
@TableName("ap_user")
public class ApUser implements Serializable {private static final long serialVersionUID = 1L;/*** 主键*/@TableId(value = "id", type = IdType.AUTO)private Integer id;/*** 密码、通信等加密盐*/@TableField("salt")private String salt;/*** 用户名*/@TableField("name")private String name;/*** 密码,md5加密*/@TableField("password")private String password;/*** 手机号*/@TableField("phone")private String phone;/*** 头像*/@TableField("image")private String image;/*** 0 男1 女2 未知*/@TableField("sex")private Boolean sex;/*** 0 未1 是*/@TableField("is_certification")private Boolean certification;/*** 是否身份认证*/@TableField("is_identity_authentication")private Boolean identityAuthentication;/*** 0正常1锁定*/@TableField("status")private Boolean status;/*** 0 普通用户1 自媒体人2 大V*/@TableField("flag")private Short flag;/*** 注册时间*/@TableField("created_time")private Date createdTime;}

手动加密(md5 + 随机字符串)

md5是不可逆加密,md5相同的密码每次加密都一样,不太安全。在md5的基础上手动加盐(salt)处理。

3. app登录

①在service模块下新建如下

bootstrap.yml配置如下:

server:port: 51801
spring:application:name: leadnews-usercloud:nacos:discovery:server-addr: 192.168.200.130:8848config:server-addr: 192.168.200.130:8848file-extension: yml

在nacos中创建配置文件 leadnews-user(注意修改数据库连接密码)

spring:datasource:driver-class-name: com.mysql.jdbc.Driverurl: jdbc:mysql://localhost:3306/leadnews_user?useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC&useSSL=falseusername: rootpassword: 123456
# 设置Mapper接口所对应的XML文件位置,如果你在Mapper接口中有自定义方法,需要进行该配置
mybatis-plus:mapper-locations: classpath*:mapper/*.xml# 设置别名包扫描路径,通过该属性可以给包中的类注册别名type-aliases-package: com.heima.model.user.pojos

logback.xml

<?xml version="1.0" encoding="UTF-8"?><configuration><!--定义日志文件的存储地址,使用绝对路径--><property name="LOG_HOME" value="e:/logs"/><!-- Console 输出设置 --><appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender"><encoder><!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符--><pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern><charset>utf8</charset></encoder></appender><!-- 按照每天生成日志文件 --><appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender"><rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"><!--日志文件输出的文件名--><fileNamePattern>${LOG_HOME}/leadnews.%d{yyyy-MM-dd}.log</fileNamePattern></rollingPolicy><encoder><pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern></encoder></appender><!-- 异步输出 --><appender name="ASYNC" class="ch.qos.logback.classic.AsyncAppender"><!-- 不丢失日志.默认的,如果队列的80%已满,则会丢弃TRACT、DEBUG、INFO级别的日志 --><discardingThreshold>0</discardingThreshold><!-- 更改默认的队列的深度,该值会影响性能.默认值为256 --><queueSize>512</queueSize><!-- 添加附加的appender,最多只能添加一个 --><appender-ref ref="FILE"/></appender><logger name="org.apache.ibatis.cache.decorators.LoggingCache" level="DEBUG" additivity="false"><appender-ref ref="CONSOLE"/></logger><logger name="org.springframework.boot" level="debug"/><root level="info"><!--<appender-ref ref="ASYNC"/>--><appender-ref ref="FILE"/><appender-ref ref="CONSOLE"/></root>
</configuration>

②接口定义

③新增LoginDto

package com.heima.model.user.dtos;import lombok.Data;@Data
public class LoginDto {/*** 手机号*/private String phone;/*** 密码*/private String password;
}

④思路分析

⑤实现

UserApplication

package com.heima.user;import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;@SpringBootApplication
@EnableDiscoveryClient
@MapperScan("com.heima.user.mapper")
public class UserApplication {public static void main(String[] args) {SpringApplication.run(UserApplication.class, args);}
}

ApUserMapper

package com.heima.user.mapper;import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.heima.model.user.pojos.ApUser;
import org.apache.ibatis.annotations.Mapper;@Mapper
public interface ApUserMapper extends BaseMapper<ApUser> {
}

ApUserService

package com.heima.user.service;import com.baomidou.mybatisplus.extension.service.IService;
import com.heima.model.common.dtos.ResponseResult;
import com.heima.model.user.dtos.LoginDto;
import com.heima.model.user.pojos.ApUser;public interface ApUserService extends IService<ApUser> {/*** app登录功能* @param dto* @return*/public ResponseResult login(LoginDto dto);
}

ApUserServiceImpl

package com.heima.user.service.impl;import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.heima.model.common.dtos.ResponseResult;
import com.heima.model.common.enums.AppHttpCodeEnum;
import com.heima.model.user.dtos.LoginDto;
import com.heima.model.user.pojos.ApUser;
import com.heima.user.mapper.ApUserMapper;
import com.heima.user.service.ApUserService;
import com.heima.utils.common.AppJwtUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.DigestUtils;import java.util.HashMap;
import java.util.Map;@Service
@Transactional
@Slf4j
public class ApUserServiceImpl extends ServiceImpl<ApUserMapper, ApUser> implements ApUserService {/*** app登录功能* @param dto* @return*/@Overridepublic ResponseResult login(LoginDto dto) {// 1. 正常登录 用户名和密码if(StringUtils.isNotBlank(dto.getPhone()) && StringUtils.isNotBlank(dto.getPassword())) {// 1.1 根据手机号查询用户信息ApUser dbUser = getOne(Wrappers.<ApUser>lambdaQuery().eq(ApUser::getPhone, dto.getPhone()));if(dbUser == null) {return ResponseResult.errorResult(AppHttpCodeEnum.DATA_NOT_EXIST, "用户信息不存在");}// 1.2 对比密码String salt = dbUser.getSalt();String password = dto.getPassword();String paswd = DigestUtils.md5DigestAsHex((password + salt).getBytes());if(!paswd.equals(dbUser.getPassword())) {return ResponseResult.errorResult(AppHttpCodeEnum.LOGIN_PASSWORD_ERROR);}// 1.3 返回数据 jwtString token = AppJwtUtil.getToken(dbUser.getId().longValue());Map<String, Object> map = new HashMap<>();map.put("token", token);dbUser.setSalt("");dbUser.setPassword("");map.put("user", dbUser);return ResponseResult.okResult(map);} else {// 2. 游客登录Map<String, Object> map = new HashMap<>();map.put("token", AppJwtUtil.getToken(0L));return ResponseResult.okResult(map);}}
}

ApUserLoginController

package com.heima.user.controller.v1;import com.heima.model.common.dtos.ResponseResult;
import com.heima.model.user.dtos.LoginDto;
import com.heima.user.service.ApUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;@RestController
@RequestMapping("/api/v1/login")
public class ApUserLoginController {@Autowiredprivate ApUserService apUserService;@PostMapping("/login_auth")public ResponseResult login(@RequestBody LoginDto dto) {return apUserService.login(dto);}
}

五、接口工具postman、swagger、knife4j

1. 接口工具-postman

Postman是一款功能强大的网页调试与发送网页HTTP请求的Chrome插件。Postman被500万开发者和超过100,000家公司用于每月访问1.3亿个API。

官网:https://www.postman.com/

登录请求的测试:http://localhost:51801/api/v1/login/login_auth

{"phone": "13511223456","password": "admin"
}

2. 接口工具-Swagger

前后端分离开发

项目基于前后端分离的架构进行开发,前后端分离架构总体上包括前端和服务端,通常是多人协作开发。

(1)简介

Swagger是一个规范和完整的框架,用于生成、描述、调用和可视化RESTful风格的Web服务。它的主要作用是:

  • 使得前后端分离开发更加方便,有利于团队协作
  • 接口的文档在线自动生成,降低后端开发人员编写接口文档的负担
  • 功能测试

(2)SpringBoot集成Swagger

①引入依赖

在heima-leadnews-model和heima-leadnews-common模块的pom.xml中引入该依赖

<dependency><groupId>io.springfox</groupId><artifactId>springfox-swagger2</artifactId>
</dependency>
<dependency><groupId>io.springfox</groupId><artifactId>springfox-swagger-ui</artifactId>
</dependency>

②在heima-leadnews-common中进行配置(其他微服务工程都直接或间接依赖common模块)

新增com.heima.coomon.swagger.SwaggerConfiguration

package com.heima.common.swagger;import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.service.Contact;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;@Configuration
@EnableSwagger2
public class SwaggerConfiguration {@Beanpublic Docket buildDocket() {return new Docket(DocumentationType.SWAGGER_2).apiInfo(buildApiInfo()).select()// 要扫描的API(Controller)基础包.apis(RequestHandlerSelectors.basePackage("com.heima")).paths(PathSelectors.any()).build();}private ApiInfo buildApiInfo() {Contact contact = new Contact("黑马程序员","","");return new ApiInfoBuilder().title("黑马头条-平台管理API文档").description("黑马头条后台api").contact(contact).version("1.0.0").build();}
}

③在heima-leadnews-common模块中的resources目录下的META-INF/spring.factories中新增如下

org.springframework.boot.autoconfigure.EnableAutoConfiguration=\com.heima.common.exception.ExceptionCatch,\com.heima.common.swagger.SwaggerConfiguration

④Swagger常用注解

注解释义
@Api修饰整个类,描述Controller的作用
@ApiOperation描述一个类的一个方法,或者说一个接口
@ApiParam单个参数的描述信息
@ApiModel用对象接收参数
@ApiModelProperty用对象接收参数时,描述对象的一个字段
@ApiResponseHTTP响应其中一个描述
@ApiResponsesHTTP响应整体描述
@ApiIgnore使用该注解忽略这个API
@ApiError发生错误返回的信息
@ApiImplicitParam一个请求参数
@ApiImplicitParams多个请求参数的描述信息

@ApiImplicitParam属性:

属性取值作用
paramType查询参数类型
path以地址的形式提交数据
query直接跟参数完成自动映射赋值
body以流的形式提交 仅支持POST
header参数在request headers 里边提交
form以form表单的形式提交 仅支持POST
dataType参数的数据类型 只作为标志说明,并没有实际验证
Long
String
name接收参数名
value接收参数的意义描述
required参数是否必填
true必填
false非必填
defaultValue默认值

在ApUserLoginController中添加Swagger注解

@RestController
@RequestMapping("/api/v1/login")
@Api(value = "app端用户登录", tags = "app端用户登录")
public class ApUserLoginController {@Autowiredprivate ApUserService apUserService;@PostMapping("/login_auth")@ApiOperation("用户登录")public ResponseResult login(@RequestBody LoginDto dto) {return apUserService.login(dto);}
}

在LoginDto添加注解

package com.heima.model.user.dtos;import io.swagger.annotations.ApiModelProperty;
import lombok.Data;@Data
public class LoginDto {/*** 手机号*/@ApiModelProperty(value = "手机号", required = true)private String phone;/*** 密码*/@ApiModelProperty(value = "密码", required = true)private String password;
}

⑤启动UserApplication

访问接口文档:http://localhost:51801/swagger-ui.html

3. 接口工具-knife4j

(1)简介

knife4j是为Java MVC框架集成Swagger生成Api文档的增强解决方案,前身是swagger-boostrap-ui,取名knife4j是希望它能像一把匕首一样小巧,并且功能强悍。

gitee地址:knife4j: Knife4j是一个集Swagger2 和 OpenAPI3为一体的增强解决方案

官方文档:Knife4j · 集Swagger2及OpenAPI3为一体的增强解决方案. | Knife4j

效果演示:http://knife4j.xiaominfo.com/doc.html

(2)核心功能

  • 文档说明:根据Swagger的规范说明,详细列出接口文档的说明,包括接口地址、类型、请求示例、请求参数、响应示例、响应参数、响应码等信息,使用swagger-bootstrap-ui能根据该文档说明,对该接口的使用情况一目了然。
  • 在线调试:提供在线接口联调的强大功能,自动解析当前接口参数,同时包含表单验证,调用参数可返回接口响应内容、headers、Curl请求命令实例、响应时间、响应状态码等信息,帮助开发者在线调试,而不必通过其他测试工具测试接口是否正确,简洁、强大。
  • 个性化设置:通过个性化ui配置项,可以自定义UI的相关显示信息
  • 离线文档:根据标准规范,生成的在线markdown离线文档,开发者可以进行拷贝生成的markdown接口文档,通过其他第三方markdown转换工具转换成html或pdf,这样也可以放弃swagger2markdown组件
  • 接口排序:自1.8.5后,ui支持了接口排序功能,例如一个注册功能主要包含了多个步骤,可以根据swagger-bootstrap-ui提供的接口排序规则实现接口的排序,step化接口操作,方便其他开发者进行接口对接。

(3)快速集成

①在heima-leadnews-common模块中的pom.xml文件中引入knife4j的依赖

<dependency><groupId>com.github.xiaoymin</groupId><artifactId>knife4j-spring-boot-starter</artifactId>
</dependency>

②创建swagger配置文件

在heima-leadnews-common模块中新建配置类SwaggerConfiguration

package com.heima.common.knife4j;import com.github.xiaoymin.knife4j.spring.annotations.EnableKnife4j;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import springfox.bean.validators.configuration.BeanValidatorPluginsConfiguration;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;@Configuration
@EnableSwagger2
@EnableKnife4j
@Import(BeanValidatorPluginsConfiguration.class)
public class Swagger2Configuration {@Bean(value = "defaultApi2")public Docket defaultApi2() {Docket docket=new Docket(DocumentationType.SWAGGER_2).apiInfo(apiInfo())//分组名称.groupName("1.0").select()//这里指定Controller扫描包路径.apis(RequestHandlerSelectors.basePackage("com.heima")).paths(PathSelectors.any()).build();return docket;}private ApiInfo apiInfo() {return new ApiInfoBuilder().title("黑马头条API文档").description("黑马头条API文档").version("1.0").build();}
}
注解说明
@EnableSwagger2该注解是Springfox-swagger框架提供的使用Swagger的注解,该注解必须添加
@EnableKnife4j该注解是knife4j提供的增强注解,Ui提供了例如动态参数、参数过滤、接口排序等增强功能,如果你想使用这些增强功能就必须加该注解,否则可以不用加

③在META-INF/spring.factories中新增配置

org.springframework.boot.autoconfigure.EnableAutoConfiguration=\com.heima.common.exception.ExceptionCatch,\com.heima.common.swagger.SwaggerConfiguration,\com.heima.common.swagger.Swagger2Configuration

④启动UserApplication

访问地址:http://localhost:51801/doc.html#/home

六、app端网关

1. app端网关

(1)网关概述

实现步骤:

①在heima-leadnews-gateway导入以下依赖

<dependencies><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-gateway</artifactId></dependency><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId></dependency><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId></dependency><dependency><groupId>io.jsonwebtoken</groupId><artifactId>jjwt</artifactId></dependency>
</dependencies>

②在heima-leadnews-gateway下创建heima-leadnews-app-gateway微服务

新增引导类AppGatewayApplication

package com.heima.app.gateway;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;@SpringBootApplication
@EnableDiscoveryClient  //开启注册中心
public class AppGatewayApplication {public static void main(String[] args) {SpringApplication.run(AppGatewayApplication.class,args);}
}

新增配置类bootstrap.yml

server:port: 51601
spring:application:name: leadnews-app-gatewaycloud:nacos:discovery:server-addr: 192.168.200.130:8848config:server-addr: 192.168.200.130:8848file-extension: yml

③在nacos添加Data ID为leadnews-app-gateway的配置文件

spring:cloud:gateway:globalcors:add-to-simple-url-handler-mapping: truecorsConfigurations:'[/**]':allowedHeaders: "*"allowedOrigins: "*"allowedMethods:- GET- POST- DELETE- PUT- OPTIONroutes:# 平台管理- id: useruri: lb://leadnews-userpredicates:- Path=/user/**filters:- StripPrefix= 1

④启动AppGatewayApplication和UserApplication

网址:http://localhost:51601/user/api/v1/login/login_auth

2. 认证过滤器

实现步骤:

①拷贝一份jwt解析工具类AppJwtUtil到网关微服务中

②在网关微服务中新建全局过滤器

package com.heima.app.gateway.filter;import com.heima.app.gateway.util.AppJwtUtil;
import io.jsonwebtoken.Claims;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.http.HttpStatus;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;@Component
@Slf4j
public class AuthorizeFilter implements Ordered, GlobalFilter {@Overridepublic Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {// 1. 获取request和response对象ServerHttpRequest request = exchange.getRequest();ServerHttpResponse response = exchange.getResponse();// 2. 判断是否是登录if(request.getURI().getPath().contains("/login")) {// 放行return chain.filter(exchange);}// 3. 获取tokenString token = request.getHeaders().getFirst("token");// 4. 判断token是否存在if(StringUtils.isBlank(token)) {response.setStatusCode(HttpStatus.UNAUTHORIZED);return response.setComplete();}// 5. 判断token是否有效try {Claims claimsBody = AppJwtUtil.getClaimsBody(token);// 判断token是否过期int result = AppJwtUtil.verifyToken(claimsBody);if (result == 1 || result == 2) {response.setStatusCode(HttpStatus.UNAUTHORIZED);return response.setComplete();}} catch (Exception e) {e.printStackTrace();response.setStatusCode(HttpStatus.UNAUTHORIZED);return response.setComplete();}// 6. 放行return chain.filter(exchange);}/*** 优先级设置:值越小,优先级越高* @return*/@Overridepublic int getOrder() {return 0;}
}

③重启AppGatewayApplication和UserApplication

如果访问其他微服务,会提示需要认证才能访问,这个时候就需要在headers中设置token才能正常访问。

七、app前端项目集成

①解压nginx-1.18.0.zip和app-web.zip到一个不带中文的路径下

②启动nginx

nginx: [emerg] bind() to 0.0.0.0:80 failed (10013: An attempt was made to access a socket in a way forbidden by its access permissions)

如果有出现上面的问题,可以查看正在占用80端口的程序,并kill掉

或者在nginx.conf把监听端口改成其他的,如8080

③在niginx安装的conf目录下新建一个文件夹leadnews.conf,在当前文件夹中新建heima-leadnews-app.conf文档,配置如下:(根据自己的情况修改前端工程路径

upstream  heima-app-gateway{server localhost:51601;
}server {listen 8801;location / {root D:/IDEA/frontProject/app-web/;index index.html;}location ~/app/(.*) {proxy_pass http://heima-app-gateway/$1;proxy_set_header HOST $host;  # 不改变源请求头的值proxy_pass_request_body on;  #开启获取请求体proxy_pass_request_headers on;  #开启获取请求头proxy_set_header X-Real-IP $remote_addr;   # 记录真实发出请求的客户端IPproxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;  #记录代理信息}
}

④把nginx.conf里面的内容覆盖为如下,引入heima-leadnews-app.conf文件加载


#user  nobody;
worker_processes  1;events {worker_connections  1024;
}
http {include       mime.types;default_type  application/octet-stream;sendfile        on;keepalive_timeout  65;# 引入自定义配置文件include leadnews.conf/*.conf;
}

⑤启动niginx,在nginx安装包中使用命令提示符打开,输入nignx启动项目

可查看进行,检查nginx是否启动。

重新加载配置文件:nginx -s reload

⑥启动UserApplication和AppGatewayApplication

访问:http://localhost:8801/

注意,要先启动nacos

相关文章:

黑马头条-环境搭建、SpringCloud

一、项目介绍 1. 项目背景介绍 项目概述 类似于今日头条&#xff0c;是一个新闻资讯类项目。 随着智能手机的普及&#xff0c;人们更加习惯于通过手机来看新闻。由于生活节奏的加快&#xff0c;很多人只能利用碎片时间来获取信息&#xff0c;因此&#xff0c;对于移动资讯客…...

基于centos2009搭建openstack-t版-ovs网络-脚本运行

openstackT版脚本 环境变量ip初始化 controlleriaas-pre.shiaas-install-mysql.shiaas-install-keystone.shiaas-install-glance.shiaas-install-placement.shiaas-install-nova-controller.shiaas-install-neutron-controller.shiaas-install-dashboard.sh computeiaas-instal…...

buuctf-web

查看后端源码 得到base64编码&#xff0c;解码得flag...

UBUNTU22 安装QT5.15.2 记录

安装QT预置安装软件包 sudo apt install gcc sudo apt install g sudo apt install clang sudo apt install clang sudo apt install make sudo snap install cmake --classic sudo apt-get install build-essential sudo apt install libxcb-xinerama0 #安装OpenGL核心库 su…...

C++基础知识:C++内存分区模型,全局变量和静态变量以及常量,常量区,字符串常量和其他常量,栈区,堆区,代码区和全局区

1.C内存分区模型 C程序在执行时&#xff0c;将内存大方向划分为4个区域 代码区:存放函数体的二进制代码&#xff0c;由操作系统进行管理的&#xff08;在编译器中所书写的代码都会存放在这个空间。&#xff09; 全局区:存放全局变量和静态变量以及常量 栈区:由编译器自动分…...

MySQL面试题-重难点

mysql中有哪些锁&#xff1f;举出所有例子&#xff0c;各个锁的作用是什么&#xff1f;区别是什么&#xff1f; 共享锁&#xff1a;也叫读锁&#xff0c;简称S锁&#xff0c;在事务要读取一条记录时&#xff0c;先获取该记录的S锁&#xff0c;别的事务也可以继续获取该记录的S…...

【Linux杂货铺】期末总结篇3:用户账户管理命令 | 组账户管理命令

&#x1f308;个人主页&#xff1a;聆风吟_ &#x1f525;系列专栏&#xff1a;Linux杂货铺、Linux实践室 &#x1f516;少年有梦不应止于心动&#xff0c;更要付诸行动。 文章目录 第五章5.1 ⛳️Linux 账户5.2 ⛳️用户配置文件和目录&#xff08;未完待续&#xff09;5.2.1 …...

基于STM32设计的超声波测距仪(微信小程序)(186)

基于STM32设计的超声波测距仪(微信小程序)(186) 文章目录 一、前言1.1 项目介绍【1】项目功能介绍【2】项目硬件模块组成1.2 设计思路【1】整体设计思路【2】ESP8266工作模式配置1.3 项目开发背景【1】选题的意义【2】可行性分析【3】参考文献1.4 开发工具的选择1.5 系统框架图…...

Web前端-Web开发HTML基础2-list

一. 基础 1. 写一个列表标签&#xff0c;生成一个有三条记录的无序列表&#xff1b; 2. 写一个列表标签&#xff0c;生成一个有四条记录的无序列表&#xff1b; 3. 写一个列表标签&#xff0c;生成一个有五条记录的无序列表&#xff1b; 4. 写一个列表标签&#xff0c;生成一个…...

MAVSDK-Java安卓客户端编译与使用完整示例

效果&#xff1a; 1.启动PX4容器 2.监听QGC连接端口 3.手机与QGC连接到同一局域网&#xff08;此例QGC为&#xff1a;192.168.6.250 手机为&#xff1a;192.168.6.86&#xff09; 4.监听手机mavsdk_server连接端口 5.使用Android Studio打开MAVSDK-JAVA下的examples/android-c…...

JavaEE:Spring Web简单小项目实践二(用户登录实现)

学习目的&#xff1a; 1、理解前后端交互过程 2、学习接口传参&#xff0c;数据返回以及页面展示 1、准备工作 创建SpringBoot项目&#xff0c;引入Spring Web依赖&#xff0c;添加前端页面到项目中。 前端代码&#xff1a; login.html <!DOCTYPE html> <html lang&…...

深度学习 | CNN 基本原理

目录 1 什么是 CNN2 输入层3 卷积层3.1 卷积操作3.2 Padding 零填充3.3 处理彩色图像 4 池化层4.1 池化操作4.2 池化的平移不变性 5 全连接层6 输出层 前言 这篇博客不够详细&#xff0c;因为没有介绍卷积操作的具体计算&#xff1b;但是它介绍了 CNN 各层次的功能…...

解读|http和https的区别,谁更好用

在日常我们浏览网页时&#xff0c;有些网站会看到www前面是http&#xff0c;有些是https&#xff0c;这两种有什么区别呢&#xff1f;为什么单单多了“s”&#xff0c;会有人说这个网页会更安全些&#xff1f; HTTP&#xff08;超文本传输协议&#xff09;和HTTPS&#xff08;…...

汽车零部件制造企业MES系统主要功能介绍

随着汽车工业的不断发展&#xff0c;汽车零部件制造企业面临着越来越高的生产效率、质量控制和成本管理要求。MES系统作为一种综合信息系统&#xff0c;能够帮助企业实现从订单接收到产品交付的全流程数字化管理&#xff0c;优化资源配置&#xff0c;提高生产效率&#xff0c;确…...

常见的五种聚类算法总结

常见的聚类算法总结 1. K-Means 聚类 描述 K-Means 是一种迭代优化的聚类算法&#xff0c;它通过最小化样本点到质心的距离平方和来进行聚类。 思想 随机选择 K 个初始质心。分配每个数据点到最近的质心&#xff0c;形成 K 个簇。重新计算每个簇的质心。重复上述步骤&…...

智能车存在网络安全隐患,如何应设计出更好的安全防护技术?

智能车网络安全防护技术的研究与设计 摘要&#xff1a;随着智能车技术的迅速发展&#xff0c;车辆的网络连接性不断增强&#xff0c;然而这也带来了诸多网络安全隐患。本文深入探讨了智能车面临的网络安全威胁&#xff0c;并提出了一系列创新的安全防护技术设计&#xff0c;旨…...

通讯的概念

通讯的概念 文章目录 通讯的概念1.通讯的基本概念2. 串行通讯与并行通讯2. 全双工、半双工及单工通讯3. 同步通讯与异步通讯4. 通讯速率 1.通讯的基本概念 通讯是指在嵌入式系统中实现数据交换的技术手段&#xff0c;它涉及到硬件与硬件、硬件与软件之间的信息传输。基本概念包…...

Centos7 rpm 安装 Mysql 8.0.28

Centos7 rpm 安装 Mysql 8.0.28 一、检查系统是否已经安装了Mysql 如果安装了则卸载 [rootiZbp1byzaznzn9jncxr010Z /]# rpm -qa | grep mysql[rootiZbp1byzaznzn9jncxr010Z /]# rpm -qa | grep mariadb mariadb-libs-5.5.68-1.el7.x86_64如果安装了 mysql &#xff0c;maria…...

Linux 多进程编程详解

Linux 多进程编程详解 多进程编程是现代操作系统中一种重要的并发编程技术。通过在同一程序中运行多个独立的进程&#xff0c;可以实现并发处理&#xff0c;充分利用多核处理器的优势&#xff0c;提高程序的运行效率。本文将详细介绍Linux多进程的基本概念、创建方法、进程间通…...

C语言之大小端理解

目录 1前言2 大小端理解与区分3 大小端的识别和基本切换操作4 总结 1前言 在汽车CAN通讯报文中往往会接触到Intel类型和motorola类型&#xff0c;实际项目中涉及到多机通讯也会接触到大小端问题 2 大小端理解与区分 大端(Big_Endian) :低字节放在高地址小端(Little_Endian):…...

生成xcframework

打包 XCFramework 的方法 XCFramework 是苹果推出的一种多平台二进制分发格式&#xff0c;可以包含多个架构和平台的代码。打包 XCFramework 通常用于分发库或框架。 使用 Xcode 命令行工具打包 通过 xcodebuild 命令可以打包 XCFramework。确保项目已经配置好需要支持的平台…...

深入浅出Asp.Net Core MVC应用开发系列-AspNetCore中的日志记录

ASP.NET Core 是一个跨平台的开源框架&#xff0c;用于在 Windows、macOS 或 Linux 上生成基于云的新式 Web 应用。 ASP.NET Core 中的日志记录 .NET 通过 ILogger API 支持高性能结构化日志记录&#xff0c;以帮助监视应用程序行为和诊断问题。 可以通过配置不同的记录提供程…...

超短脉冲激光自聚焦效应

前言与目录 强激光引起自聚焦效应机理 超短脉冲激光在脆性材料内部加工时引起的自聚焦效应&#xff0c;这是一种非线性光学现象&#xff0c;主要涉及光学克尔效应和材料的非线性光学特性。 自聚焦效应可以产生局部的强光场&#xff0c;对材料产生非线性响应&#xff0c;可能…...

椭圆曲线密码学(ECC)

一、ECC算法概述 椭圆曲线密码学&#xff08;Elliptic Curve Cryptography&#xff09;是基于椭圆曲线数学理论的公钥密码系统&#xff0c;由Neal Koblitz和Victor Miller在1985年独立提出。相比RSA&#xff0c;ECC在相同安全强度下密钥更短&#xff08;256位ECC ≈ 3072位RSA…...

Qt/C++开发监控GB28181系统/取流协议/同时支持udp/tcp被动/tcp主动

一、前言说明 在2011版本的gb28181协议中&#xff0c;拉取视频流只要求udp方式&#xff0c;从2016开始要求新增支持tcp被动和tcp主动两种方式&#xff0c;udp理论上会丢包的&#xff0c;所以实际使用过程可能会出现画面花屏的情况&#xff0c;而tcp肯定不丢包&#xff0c;起码…...

理解 MCP 工作流:使用 Ollama 和 LangChain 构建本地 MCP 客户端

&#x1f31f; 什么是 MCP&#xff1f; 模型控制协议 (MCP) 是一种创新的协议&#xff0c;旨在无缝连接 AI 模型与应用程序。 MCP 是一个开源协议&#xff0c;它标准化了我们的 LLM 应用程序连接所需工具和数据源并与之协作的方式。 可以把它想象成你的 AI 模型 和想要使用它…...

Vue2 第一节_Vue2上手_插值表达式{{}}_访问数据和修改数据_Vue开发者工具

文章目录 1.Vue2上手-如何创建一个Vue实例,进行初始化渲染2. 插值表达式{{}}3. 访问数据和修改数据4. vue响应式5. Vue开发者工具--方便调试 1.Vue2上手-如何创建一个Vue实例,进行初始化渲染 准备容器引包创建Vue实例 new Vue()指定配置项 ->渲染数据 准备一个容器,例如: …...

CMake控制VS2022项目文件分组

我们可以通过 CMake 控制源文件的组织结构,使它们在 VS 解决方案资源管理器中以“组”(Filter)的形式进行分类展示。 🎯 目标 通过 CMake 脚本将 .cpp、.h 等源文件分组显示在 Visual Studio 2022 的解决方案资源管理器中。 ✅ 支持的方法汇总(共4种) 方法描述是否推荐…...

用机器学习破解新能源领域的“弃风”难题

音乐发烧友深有体会&#xff0c;玩音乐的本质就是玩电网。火电声音偏暖&#xff0c;水电偏冷&#xff0c;风电偏空旷。至于太阳能发的电&#xff0c;则略显朦胧和单薄。 不知你是否有感觉&#xff0c;近两年家里的音响声音越来越冷&#xff0c;听起来越来越单薄&#xff1f; —…...

A2A JS SDK 完整教程:快速入门指南

目录 什么是 A2A JS SDK?A2A JS 安装与设置A2A JS 核心概念创建你的第一个 A2A JS 代理A2A JS 服务端开发A2A JS 客户端使用A2A JS 高级特性A2A JS 最佳实践A2A JS 故障排除 什么是 A2A JS SDK? A2A JS SDK 是一个专为 JavaScript/TypeScript 开发者设计的强大库&#xff…...