二刷蒼穹外賣 day01

nginx

nginx反向代理

將前端發送的請求由nginx轉發到后端服務器
好處:
提速:nginx本身可緩存數據
負載均衡:配置多臺服務器,大量請求來臨可均衡分配
保證后端安全:不暴露后端服務真實地址

server{listen 80;server_name localhost;location /api/{proxy_pass http://localhost:8080/admin/; #反向代理}
}

**proxy_pass:**該指令是用來設置代理服務器的地址,可以是主機名稱,IP地址加端口號等形式。

如上代碼的含義是:監聽80端口號, 然后當我們訪問 http://localhost:80/api/…/…這樣的接口的時候,它會通過 location /api/ {} 這樣的反向代理到 http://localhost:8080/admin/上來。

負載均衡

upstream webservers{server 192.168.100.128:8080;server 192.168.100.129:8080;
}
server{listen 80;server_name localhost;location /api/{proxy_pass http://webservers/admin;#負載均衡}
}

upstream:如果代理服務器是一組服務器,可以使用upstream指令配置后端服務器
如上代碼的含義是:監聽80端口號, 然后當我們訪問 http://localhost:80/api/…/…這樣的接口的時候,它會通過 location /api/ {} 這樣的反向代理到 http://webservers/admin,根據webservers名稱找到一組服務器,根據設置的負載均衡策略(默認是輪詢)轉發到具體的服務器。

注:upstream后面的名稱可自定義,但要上下保持一致。

負載策略:

輪詢:默認

upstream webservers{server 192.168.100.128:8080;server 192.168.100.129:8080;
}

weight:添加權重

upstream webservers{server 192.168.100.128:8080 weight=90;server 192.168.100.129:8080 weight=10;
}

配置前端環境

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 {include mime.types;default_type application/json;sendfile on;keepalive_timeout 65;upstream webservers{server 127.0.0.1:8080 weight=90 ;#server 127.0.0.1:8088 weight=10 ;}server {listen 80;server_name localhost;# 指定前端項目所在的位置location / {root html/sky;index index.html index.htm;}error_page 500 502 503 504 /50x.html;location = /50x.html {root html;}# location /api {# default_type application/json;# #internal;# keepalive_timeout 30s;# keepalive_requests 1000;# #支持keep-alive# proxy_http_version 1.1;# rewrite /api(/.*) $1 break;# proxy_pass_request_headers on;# #more_clear_input_headers Accept-Encoding;# proxy_next_upstream error timeout;# #proxy_pass http://127.0.0.1:8081;# proxy_pass http://backend;# }# 反向代理,處理管理端發送的請求location /api/ {proxy_pass http://localhost:8080/admin/;#proxy_pass http://webservers/admin/;}# 反向代理,處理用戶端發送的請求location /user/ {proxy_pass http://webservers/user/;}# WebSocket# location /ws/ {# proxy_pass http://webservers/ws/;# proxy_http_version 1.1;# proxy_read_timeout 3600s;# proxy_set_header Upgrade $http_upgrade;# proxy_set_header Connection "$connection_upgrade";# }}# upstream backend {# server 127.0.0.1:8080 weight=90 ;# # server 127.0.0.1:8081 max_fails=5 fail_timeout=10s weight=1;# # server 127.0.0.1:8082 max_fails=5 fail_timeout=10s weight=1;# }}

輸入nginx -s reload重啟服務,訪問80端口有效
![[Pasted image 20250610191304.png]]

項目整體架構:

sky-take-out 父工程,通過pom統一管理依賴版本并聚合其他子模塊
sky-common 存放常量,工具類,異常類等子模塊
sky-pojo 存放實體,VO、DTO等
sky-server 子模塊,存放配置文件、Controller、Service、mapper等配置文件

common:

constant 相關常量
context 上下文
enumeration 枚舉操作
exception 自定義異常
json 處理json轉換 基于jackson將Java對象轉為json,或者將json轉為Java對象
properties 存放springboot相關配置屬性類,如阿里OSS服務,jwt令牌和微信支付接口等配置
result 返回結果封裝,分頁返回類和標準返回格式

Serializable接口是Java提供的一個標記接口,用于表示一個類的對象是否可被序列化,序列化意味著將對象轉換為字節流,還能從字節重構對象,
- 一個類只有實現了 Serializable 接口,它的對象才是可序列化的。因此如果要序列化某些類的對象,這些類就必須實現 Serializable 接口。而實際上,Serializable 的源碼是一個空接口,沒有什么具體內容,它的目的只是簡單的標識一個類的對象可以被序列化。

util 常見工具類

pojo

entity :存放與數據庫表對應的實體
DTO :數據傳輸對象,在后端各層中進行傳輸
VO :視圖,用于為前端展示數據所提供的對象

server

config:配置類
controller
interceptor:攔截器類
mapper:
service:
SkyApplication :啟動類

前后端整體實現思路:

![[Pasted image 20250610195506.png]]

controller層:

@PostMapping("/login")  
public Result<EmployeeLoginVO> login(@RequestBody EmployeeLoginDTO employeeLoginDTO) {  log.info("員工登錄:{}", employeeLoginDTO);  Employee employee = employeeService.login(employeeLoginDTO);  //登錄成功后,生成jwt令牌  Map<String, Object> claims = new HashMap<>();  claims.put(JwtClaimsConstant.EMP_ID, employee.getId());  String token = JwtUtil.createJWT(  jwtProperties.getAdminSecretKey(),  jwtProperties.getAdminTtl(),  claims);  EmployeeLoginVO employeeLoginVO = EmployeeLoginVO.builder()  .id(employee.getId())  .userName(employee.getUsername())  .name(employee.getName())  .token(token)  .build();  return Result.success(employeeLoginVO);  
}
1.接受登陸請求:

方法接收了一個EmplyeeLoginDTO類型的參數,這個DTO包括前端傳來的用戶名和密碼,用于員工登陸,@RequestBody注解表示請求體以JSON格式傳遞

2.調用Service層進行驗證

調用emplyeeService的login()方法,將登陸信息傳遞給服務層,服務層若驗證成功會返回對應的Employee實體對象

3.生成JWT Token

使用JwtUtil.createJWT()方法根據員工id生成JWT令牌
令牌包括用戶標識emplyee.getId()
過期時間以及簽名算法

4.構建返回值對象給EmployeeLoginVO

創建EmployeeLoginVO對象,封裝登錄成功后需要返回給前端的信息
包括員工ID,用戶名、姓名,token(用于后續請求的身份憑證)

service層:

public Employee login(EmployeeLoginDTO employeeLoginDTO) {  String username = employeeLoginDTO.getUsername();  String password = employeeLoginDTO.getPassword();  //1、根據用戶名查詢數據庫中的數據  Employee employee = employeeMapper.getByUsername(username);  //2、處理各種異常情況(用戶名不存在、密碼不對、賬號被鎖定)  if (employee == null) {  //賬號不存在  throw new AccountNotFoundException(MessageConstant.ACCOUNT_NOT_FOUND);  }  //密碼比對  // TODO 后期需要進行md5加密,然后再進行比對  if (!password.equals(employee.getPassword())) {  //密碼錯誤  throw new PasswordErrorException(MessageConstant.PASSWORD_ERROR);  }  if (employee.getStatus() == StatusConstant.DISABLE) {  //賬號被鎖定  throw new AccountLockedException(MessageConstant.ACCOUNT_LOCKED);  }  //3、返回實體對象  return employee;  
}

1.獲取用戶名與密碼

從傳入的DTO中提取用戶名和密碼

2.查詢數據庫中的員工信息

emplyeeMapper.getByUsername(Username),通過MyBatis框架調用數據庫接口

3.異常處理邏輯

異常類型:AccountNofFoundException(用戶名不存在)

4.密碼比對并檢查賬號狀態

5.返回員工實體

所有校驗通過后,返回查詢到的員工對象,該對象將用于生成JWT Token,并構建成功響應

Mapper層

@Select("select * from employee where username = #{username}")  
Employee getByUsername(String username);

這部分代碼定義了一個名為getByUsername的方法,該方法接收一個String類型的參數username@Select注解表示這是一個用于執行 SQL 查詢的語句,其注解內的 SQL 語句select * from employee where username = #{username} 意思是從名為employee的表中查詢所有列,條件是username字段的值等于傳入的username參數值。方法返回類型為Employee,即查詢結果會封裝成Employee對象返回,整體功能是根據給定的用戶名從employee表中獲取對應的員工信息。

完善登錄功能:

Employee employee = employeeMapper.getByUsername(username);  
log.info("password={}",password);

使用MD5加密的方式對明文密碼進行加密得到:
e10adc3949ba59abbe56e057f20f883e
將sql里的admin密碼從123456改為以上

     password = DigestUtils.md5DigestAsHex(password.getBytes());if (!password.equals(employee.getPassword())) {//密碼錯誤throw new PasswordErrorException(MessageConstant.PASSWORD_ERROR);}

修改代碼后登陸成功

Swagger

用于生成、描述、調用和可視化RESful風格的Web服務,作用:
使得前后端分離開發更加方便
接口文檔自動生成,減輕后端開發人員編寫借口的負擔
可進行功能測試
knife4j是為Java MVC框架集成Swagger生成Api文檔的增強解決方案,前身是swagger-bootstrap-ui,取名kni4j是希望它能像一把匕首一樣小巧,輕量,并且功能強悍!

目前,一般都使用knife4j框架。

步驟

1.導入pom坐標

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

2.在配置類中加入knife4j相關配置

WebMvcConfiguration.java

/*** 通過knife4j生成接口文檔* @return
*/@Beanpublic Docket docket() {ApiInfo apiInfo = new ApiInfoBuilder().title("蒼穹外賣項目接口文檔").version("2.0").description("蒼穹外賣項目接口文檔").build();Docket docket = new Docket(DocumentationType.SWAGGER_2).apiInfo(apiInfo).select().apis(RequestHandlerSelectors.basePackage("com.sky.controller")).paths(PathSelectors.any()).build();return docket;}

3.設置靜態資源映射

WebMvcConfiguration.java

/*** 設置靜態資源映射* @param registry
*/
protected void addResourceHandlers(ResourceHandlerRegistry registry) {registry.addResourceHandler("/doc.html").addResourceLocations("classpath:/META-INF/resources/");registry.addResourceHandler("/webjars/**").addResourceLocations("classpath:/META-INF/resources/webjars/");
}

4.訪問

在http://localhost:8080/doc.html頁面進行訪問

常見注解

@Api 類上,例如Controller,說明類
@ApiModel 用于類,例如entity,DTO,VO
@ApiModelProperty 用于屬性,描述屬性信息
@ApiOperation 用于方法上,說明方法用途、作用

使用上述注解,生成可讀性更好的接口文檔

@ApiModel(description = "員工登錄時傳遞的數據模型")
public class EmployeeLoginDTO implements Serializable @ApiModel(description = "員工登錄返回的數據格式")
public class EmployeeLoginVO implements Serializable@ApiOperation(value = "員工登錄")public Result<EmployeeLoginVO> login(@RequestBody EmployeeLoginDTO employeeLoginDTO) 

總結

1. Nginx 反向代理的作用是什么?如何配置?

作用

  • 轉發前端請求到后端服務器,隱藏真實地址,保障安全;
  • 緩存數據提速,支持負載均衡分配多臺服務器請求。
    配置示例
server {listen 80;server_name localhost;location /api/ {proxy_pass http://localhost:8080/admin/;  # 反向代理到后端地址}
}
2. Nginx 負載均衡的策略有哪些?如何配置權重?

常見策略

  • 輪詢(默認):請求依次分配到各服務器;
  • weight 權重:按權重比例分配,適用于性能不同的服務器。
    權重配置示例
upstream webservers {server 192.168.100.128:8080 weight=90;  # 權重90%server 192.168.100.129:8080 weight=10;  # 權重10%
}
3. 蒼穹外賣項目的整體架構如何設計?各模塊的作用是什么?

架構設計

  • sky-take-out:父工程,管理依賴版本并聚合子模塊;
  • sky-common:存放常量、工具類、異常類等公共資源;
  • sky-pojo:定義實體類(Entity)、數據傳輸對象(DTO)、視圖對象(VO);
  • sky-server:核心模塊,包含配置、Controller、Service、Mapper 等業務邏輯。
4. 登錄功能的后端實現流程是什么?如何保證密碼安全?

流程

  1. Controller 層:接收前端登錄請求,解析用戶名和密碼;
  2. Service 層:根據用戶名查詢數據庫,驗證密碼和賬號狀態(是否鎖定);
  3. 生成 JWT 令牌:登錄成功后,基于員工 ID 生成令牌并返回給前端。
    密碼安全
    使用 MD5 加密算法對明文密碼加密
password = DigestUtils.md5DigestAsHex(password.getBytes());  // 加密后比對
5. 什么是 Knife4j?如何配置接口文檔?

Knife4j
是 Swagger 的增強解決方案,用于自動生成、可視化 RESTful 接口文檔,簡化前后端協作。
配置步驟

  1. 導入依賴:
<dependency><groupId>com.github.xiaoymin</groupId><artifactId>knife4j-spring-boot-starter</artifactId>
</dependency>
  1. 配置 Docket Bean(如 WebMvcConfiguration):
@Bean
public Docket docket() {return new Docket(DocumentationType.SWAGGER_2).apiInfo(new ApiInfoBuilder().title("接口文檔").build()).select().apis(RequestHandlerSelectors.basePackage("com.sky.controller")).build();
}
  1. 訪問地址:http://localhost:8080/doc.html
6. JWT 令牌在登錄功能中的作用是什么?如何生成?

作用

  • 作為用戶身份憑證,避免每次請求都查詢數據庫;
  • 實現無狀態認證,減輕服務器負擔。
// 基于員工ID生成JWT令牌
Map<String, Object> claims = new HashMap<>();
claims.put("empId", employee.getId());
String token = JwtUtil.createJWT(secretKey,          // 簽名密鑰ttlMillis,          // 過期時間claims              // 載荷數據
);

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/84488.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/84488.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/84488.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

5.2 HarmonyOS NEXT應用性能診斷與優化:工具鏈、啟動速度與功耗管理實戰

HarmonyOS NEXT應用性能診斷與優化&#xff1a;工具鏈、啟動速度與功耗管理實戰 在HarmonyOS NEXT的全場景生態中&#xff0c;應用性能直接影響用戶體驗。通過專業的性能分析工具鏈、針對性的啟動速度優化&#xff0c;以及精細化的功耗管理&#xff0c;開發者能夠構建"秒…

模型訓練-關于token【低概率token, 高熵token】

Qwen團隊新發現&#xff1a;大模型推理能力的提高僅由少數高熵 Token 貢獻 不要讓低概率token主導了LLM的強化學習過程 一 低概率詞元問題 論文&#xff1a;Do Not Let Low-Probability Tokens Over-Dominate in RL for LLMs 在RL訓練過程中&#xff0c;低概率詞元&#xff08…

XCTF-web-easyupload

試了試php&#xff0c;php7&#xff0c;pht&#xff0c;phtml等&#xff0c;都沒有用 嘗試.user.ini 抓包修改將.user.ini修改為jpg圖片 在上傳一個123.jpg 用蟻劍連接&#xff0c;得到flag

gRPC、WebSocket 與 HTTP 的核心區別對比

gRPC、WebSocket 與 HTTP 的核心區別對比&#xff0c;涵蓋通信模式、協議特性及適用場景&#xff1a; &#x1f504; ?一、通信模式? ?HTTP? ?單向請求-響應?&#xff1a;客戶端發起請求&#xff0c;服務器返回響應后連接立即關閉13。?無狀態協議?&#xff1a;每次請求…

Android第十三次面試總結(四大 組件基礎)

Activity生命周期和四大啟動模式詳解 一、Activity 生命周期 Activity 的生命周期由一系列回調方法組成&#xff0c;用于管理其創建、可見性、焦點和銷毀過程。以下是核心方法及其調用時機&#xff1a; ?onCreate()?? ?調用時機?&#xff1a;Activity 首次創建時調用。?…

講講JVM的垃圾回收機制

垃圾回收就是對內存堆中已經死亡或者長時間沒有使用的對象進行清楚或回收。 JVM 在做 GC 之前&#xff0c;會先搞清楚什么是垃圾&#xff0c;什么不是垃圾&#xff0c;通常會通過可達性分析算法來判斷對象是否存活。 在確定了那些垃圾可以被回收后&#xff0c;垃圾回收器&…

QT軟件外包開發費用

國內QT軟件外包開發費用是一個非常復雜的問題&#xff0c;沒有一個固定的價格&#xff0c;它受到多種因素的影響。以下將詳細闡述影響QT軟件外包開發費用的主要因素&#xff0c;并提供大致的價格區間供參考&#xff08;請注意&#xff0c;這些價格僅為估算&#xff0c;實際報價…

iOS 16 SwiftUI 優雅跳轉實踐:用枚舉路由和 NavigationStack 實現多頁面導航

引言&#xff1a;跳轉的混亂與優雅的必要性 SwiftUI 給我們帶來了聲明式界面的全新開發體驗&#xff0c;但當涉及到頁面跳轉時&#xff0c;許多開發者仍然面臨一些“舊痛”。最初的 NavigationLink(destination:isActive:) 或 sheet(isPresented:) 等方式雖然能用&#xff0c;…

TikTok矩陣養號實戰:住宅IP純凈度與設備指紋聯動方案

在TikTok矩陣運營中&#xff0c;住宅IP純凈度和設備指紋管理是規避風控的核心。以下方案整合多平臺風控邏輯與實戰數據&#xff0c;覆蓋環境隔離、行為模擬到風險防控全流程。 &#x1f527; 一、住宅IP純凈度維持策略 IP篩選與驗證 靜態住宅IP優選&#xff1a;核心賬號綁定目標…

Elasticsearch增刪改查語句

創建索引庫&#xff1a;不帶映射的 PUT /索引名稱 {"settings": {"number_of_shards": 3, // 主分片數"number_of_replicas": 1 // 每個主分片的副本數} } 創建帶映射的索引庫&#xff1a; PUT /products {"settings": {"…

樹莓派4B, ubuntu20.04, 安裝Ros Noetic[踩坑記錄]

一、安裝過程 1. 硬件要求 樹莓派4B (建議4GB或8GB內存版本) 至少16GB的microSD卡 2. 下載并安裝Ubuntu 20.04 Ubuntu 20.04 LTS (Focal Fossa) for Raspberry Pi 使用Raspberry Pi Imager或BalenaEtcher將鏡像寫入microSD卡 3. 安裝ROS Noetic ?# 設置sources.list s…

視覺slam--框架

視覺里程計的框架 傳感器 VO--front end VO的缺點 后端--back end 后端對什么數據進行優化 利用什么數據進行優化的 后端是怎么進行優化的 回環檢測 建圖 建圖是指構建地圖的過程。 構建的地圖是點云地圖還是什么信息的地圖&#xff1f; 建圖并沒有一個固定的形式和算法…

每日算法 -【Swift 算法】刪除鏈表的倒數第 N 個結點

?? Swift | 刪除鏈表的倒數第 N 個結點(含詳細注釋) 在刷算法題時,我們經常會遇到關于鏈表的題目,而「刪除鏈表的倒數第 N 個節點」是其中一個非常經典的題。今天我們就用 Swift 來實現它,并梳理清楚整個思路。 ?? 一、題目描述 給你一個鏈表,刪除鏈表的倒數第 n 個…

Truffle 和 Ganache 使用指南

Truffle 和 Ganache 使用指南 Truffle 命令詳解 Truffle 是一個流行的以太坊開發框架,提供了許多有用的命令來簡化智能合約的開發、測試和部署。 常用 Truffle 命令 初始化項目 truffle init 創建一個新的 Truffle 項目結構。 編譯合約 truffle compile 編譯項目中的 Solid…

docker進階之架構

一、OCI 名為OCI&#xff0c;全稱 Open Container Initiative/開放容器倡議,其目的主要是為了制定容器技術的通用技術標準。目前主要有兩種標準&#xff1a; 1、容器運行時標準 &#xff08;runtime spec&#xff09; 2、容器鏡像標準&#xff08;image spec&#xff09; …

企業產品網絡安全日志6月10日-WAF資費消耗排查

發生了什么事&#xff1f; 上個的費用賬單出來了&#xff0c;WAF費用有點飆升。比平時多了50%到100%。 周五的時候就已經知道這個事情了&#xff0c;但當時考慮肯定是攔截了一些惡意請求&#xff0c;所以。 反正也是上個月的事情了&#xff0c;所以周一過來復盤一下 數了下&a…

vue3+el-table 利用插槽自定義數據樣式

<el-table-column label"匹配度" prop"baseMatchingLevel"><template #default"scope"><div :style"{ color: scope.row.baseMatchingLevel > 0.8 ? #00B578 : #FA5151 }">{{ scope.row.baseMatchingLevel }}&l…

[密碼學實戰]C語言使用SDF庫構建國密算法RESTful服務(五)

[密碼學實戰]C語言使用SDF庫構建國密算法RESTful服務(五) 引言 在現代信息安全領域,國密算法(SM系列算法)作為中國自主研發的密碼算法標準,在金融、政務等領域得到廣泛應用。本文將詳細介紹如何使用C語言結合SDF(Security Device Function)庫,構建一個提供國密算法服…

ubuntu 22.04搭建SOC開發環境

目錄 AArch64位編譯器命名規則 安裝交叉工具鏈編譯 安裝aarch64-none-elf工具鏈 安裝aarch64-none-linux-gnu工具鏈 啟動板載系統 板卡啟動方式 硬件連接 準備階段 硬件連接 udev規則配置 啟動流程 開發板外觀圖 硬件準備清單 硬件連接 SSH登錄系統 設置Windows為…

push [特殊字符] present

push &#x1f19a; present 前言present和dismiss特點代碼演示 push和pop特點代碼演示 前言 在 iOS 開發中&#xff0c;push 和 present 是兩種不同的視圖控制器切換方式&#xff0c;它們有著顯著的區別。 present和dismiss 特點 在當前控制器上方新建視圖層級需要手動調用…