Optimization of Reggie Takeout 03(Deployment of Frontend & Backend Separated Project)

This blog is based on the video course “Reggie Takeout” by Black Horse Programmers. It summarizes course notes, related knowledge points, and potential solutions to issues. Additionally, it includes features not implemented in the course for your reference. The notes are comprehensive and well-organized, aiming to help you in learning and understanding this takeout project.

For the full project notes, visit: Food Delivery System Notes Collection

Problem Description:

  • Developers are responsible for both frontend and backend code development, leading to unclear division of tasks.
  • Low development efficiency.
  • Frontend and backend code are mixed in a single project, making management difficult.
  • High skill requirements for developers, making recruitment challenging.

Image

Solution:

Transition from mixed development of frontend and backend code → to separate development of frontend and backend code.

1. Frontend-Backend Separation

1.1 Introduction

Frontend-backend separation development involves assigning frontend code development to dedicated frontend developers and backend code to backend developers. This ensures clear division of labor, improves efficiency, and allows for parallel development of frontend and backend code, thereby accelerating project progress.

This development approach is increasingly adopted by companies, becoming a mainstream method in modern project development. It also changes the project structure, separating frontend and backend code into distinct projects instead of mixing them in a single Maven project.

Image

1.2 Development Workflow

When frontend-backend separation is adopted, the challenge is how frontend and backend developers collaborate effectively to develop a project. The process can follow the steps below:

Image

An API is essentially an HTTP request endpoint defining the request path, method, parameters, and response data, among other aspects.

Image

1.3 Frontend Technology Stack (For Reference)

Development Tools

  • Visual Studio Code
  • Hbuilder

Frameworks and Libraries

  • Node.js
  • Vue
  • ElementUI
  • Mock
  • Webpack

2. YApi - API Definition

2.1 Overview

YApi is a powerful, easy-to-use API management platform designed to provide elegant API management services for developers, product managers, and testers. It helps developers create, publish, and maintain APIs easily while offering excellent user experience. With YApi, API development becomes simpler, more efficient, and easier to manage and collaborate on.

Source code: GitHub - YApi

YApi requires downloading and deploying the source code for use.

2.2 Features

Using YApi, you can:

  • Add projects
  • Add categories
  • Add APIs
  • Edit APIs
  • View APIs

Image
Image


3. Swagger

3.1 Overview

With Swagger, you can define APIs and related information according to its standards. Using tools and projects derived from Swagger, you can generate API documentation in various formats, as well as online API testing pages.

Official site: Swagger

Knife4j enhances Swagger integration with Java MVC frameworks for generating API documentation.

3.2 Usage Steps

  1. Add Knife4j dependency to Maven:

    1
    2
    3
    4
    5
    <dependency>
    <groupId>com.github.xiaoymin</groupId>
    <artifactId>knife4j-spring-boot-starter</artifactId>
    <version>3.0.2</version>
    </dependency>
  2. Add Knife4j configuration:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    @Configuration
    @EnableSwagger2
    @EnableKnife4j
    public class WebMvcConfig extends WebMvcConfigurationSupport {
    @Bean
    public Docket createRestApi() {
    return new Docket(DocumentationType.SWAGGER_2)
    .apiInfo(apiInfo())
    .select()
    .apis(RequestHandlerSelectors.basePackage("com.kxzhu.reggie.controller"))
    .paths(PathSelectors.any())
    .build();
    }

    private ApiInfo apiInfo() {
    return new ApiInfoBuilder()
    .title("Reggie Takeout")
    .version("1.0")
    .description("API Documentation for Reggie Takeout")
    .build();
    }
    }
  3. Configure static resources:

    1
    2
    registry.addResourceHandler("doc.html").addResourceLocations("classpath:/META-INF/resources/");
    registry.addResourceHandler("/webjars/**").addResourceLocations("classpath:/META-INF/resources/webjars/");
  4. Exclude paths from processing in LoginCheckFilter:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    String[] urls = {
    "/employee/login",
    "/employee/logout",
    "/backend/**",
    "/front/**",
    "/common/**",
    "/user/sendMsg",
    "/user/login",
    "/doc.html",
    "/webjars/**",
    "/swagger-resources",
    "/v2/api-docs"
    };

3.3 Common Annotations

Image

4. Project Deployment

4.1 Deployment Architecture

Image

4.2 Deployment Environment

Server Details

  • 192.168.138.100 (Server A):

    • Nginx: Hosts frontend project, configures reverse proxy.
    • MySQL: Primary database in a master-slave replication setup.
  • 192.168.138.101 (Server B):

    • JDK: Runs Java projects.
    • Git: Version control tool.
    • Maven: Project build tool.
    • JAR: Runs Spring Boot projects using embedded Tomcat.
    • MySQL: Secondary database in a master-slave replication setup.
  • 172.17.2.94 (Server C):

    • Redis: Caching middleware.

4.3 Frontend Deployment

  1. Install Nginx on Server A and upload the day03/dist directory to /usr/local/nginx/html.
    image

  2. Modify nginx.conf:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    server {
    listen 80;
    server_name localhost;

    location / {
    root html/dist; # Points to the dist directory uploaded to /usr/local/nginx/html
    index index.html; # Refers to the index.html file inside the dist directory
    }

    location ^~ /api/ {
    rewrite ^/api/(.*)$ /$1 break; # Rewrites the URL path
    proxy_pass http://192.168.138.101:8080; # Tomcat server address, where the backend code is deployed
    }
    }
  3. Start Nginx service:
    In the /usr/local/nginx/sbin directory, start the service by running the command:

    1
    ./nginx
  4. Reload configuration:

    1
    ./nginx -s reload
  5. Access the frontend via 192.168.138.100:80(Nginx server). Since the index.html file configured in the Nginx configuration file is loaded, you should see the default homepage.

If the access fails, remember to disable the firewall using the command:

1
systemctl stop firewalld

Explanation of Reverse Proxy Configuration:

When you click the login button on the homepage, a request will be sent to 192.168.138.100/api/employee/login. This request will be handled by the following location block:

1
2
3
4
5
# Reverse proxy configuration
location ^~ /api/ {
rewrite ^/api/(.*)$ /$1 break; # Rewrite the URL path
proxy_pass http://192.168.138.101:8080; # Tomcat server address where the backend code is deployed
}

Without the rewrite directive, the reverse proxy server will forward the request to the Tomcat server at 192.168.138.101:8080/api/employee/login. However, the backend server cannot process this request because it expects the path /employee/login. Therefore, the proxy path needs to be adjusted.

The rewrite directive rewrites the URL path to /employee/login. After the reverse proxy forwards the request to 192.168.138.101:8080/employee/login, it matches the backend service correctly.

4.4 Backend Deployment

  1. Install jdk, git, maven, and MySQL on Server B.
    Use the git clone command to clone the code from the Git remote repository into the /usr/local/javaapp directory.

Image

  1. Upload the reggieStart.sh file provided in the materials to Server B.

  2. Run the reggieStart.sh script to automatically deploy the project:

    1
    ./reggieStart.sh

    After starting, you can use the following command to check the process:

    1
    ps -ef | grep java
  3. Resolve Image Display Issues in the Backend:

  • View logs:
    Navigate to the target directory of the project, where a file named reggie_take_out.log is generated.
    Use the following command to view the logs in real-time: tail -f reggie_take_out.log

  • Identify Error:
    The logs may show a FileNotFoundException, indicating that the path configured in Application.yml does not exist on the Linux server. The image path needs to be modified.

  • Modify Code:
    Update path in IDEA’s Application.yml: path: /usr/local/img
    Push changes to remote repository

  • Re-execute Script:
    Run the deployment script again: ./reggieStart.sh

  • Upload Images:
    Transfer local images to /usr/local/img directory on Server B.