畅购电商项目-03-用户登录-2021-06-15

4.8用户登录

4.8.1构建页面:Login.vue

  • 步骤一:创建Login.vue
    在这里插入图片描述
  • 步骤二:绘制通用模块
<template>
  <div>
    <TopNav></TopNav>
    <div style="clear:both;"></div>
    <HeaderLogo></HeaderLogo>
    <div style="clear:both;"></div>
    <!-- 正文 -->
    
    <div style="clear:both;"></div>
    <Footer></Footer>
  </div>
</template>

<script>
import TopNav from '../components/TopNav'
import HeaderLogo from '../components/HeaderLogo'
import Footer from '../components/Footer'
export default {
  head: {
    title: '用户登录',
    link: [
      {rel:'stylesheet',href:'style/login.css'}
    ],
    script: [
    ]
  },
  components : {
    TopNav,
    HeaderLogo,
    Footer
  },

}
</script>

<style>

</style>

  • 步骤三:绘制登录表单
<template>
  <div>
    <TopNav></TopNav>
    <div style="clear:both;"></div>
    <HeaderLogo></HeaderLogo>
    <div style="clear:both;"></div>
    <!-- 正文 -->
    <!-- 登录主体部分start -->
    <div class="login w990 bc mt10">
      <div class="login_hd">
        <h2>用户登录</h2>
        <b></b>
      </div>
      <div class="login_bd">
        <div class="login_form fl">
          <form action="" method="post">
            <ul>
              <li>
                <label for="">用户名:</label>
                <input type="text" class="txt" name="username" />
              </li>
              <li>
                <label for="">密码:</label>
                <input type="password" class="txt" name="password" />
                <a href="">忘记密码?</a>
              </li>
              <li class="checkcode">
                <label for="">验证码:</label>
                <input type="text"  name="checkcode" />
                <img src="images/checkcode1.jpg" alt="" />
                <span>看不清?<a href="">换一张</a></span>
              </li>
              <li>
                <label for="">&nbsp;</label>
                <input type="checkbox" class="chb"  /> 保存登录信息
              </li>
              <li>
                <label for="">&nbsp;</label>
                <input type="submit" value="" class="login_btn" />
              </li>
            </ul>
          </form>

          <div class="coagent mt15">
            <dl>
              <dt>使用合作网站登录商城:</dt>
              <dd class="qq"><a href=""><span></span>QQ</a></dd>
              <dd class="weibo"><a href=""><span></span>新浪微博</a></dd>
              <dd class="yi"><a href=""><span></span>网易</a></dd>
              <dd class="renren"><a href=""><span></span>人人</a></dd>
              <dd class="qihu"><a href=""><span></span>奇虎360</a></dd>
              <dd class=""><a href=""><span></span>百度</a></dd>
              <dd class="douban"><a href=""><span></span>豆瓣</a></dd>
            </dl>
          </div>
        </div>

        <div class="guide fl">
          <h3>还不是商城用户</h3>
          <p>现在免费注册成为商城用户,便能立刻享受便宜又放心的购物乐趣,心动不如行动,赶紧加入吧!</p>

          <a href="regist.html" class="reg_btn">免费注册 >></a>
        </div>

      </div>
    </div>
    <!-- 登录主体部分end -->
    <div style="clear:both;"></div>
    <Footer></Footer>
  </div>
</template>

<script>
import TopNav from '../components/TopNav'
import HeaderLogo from '../components/HeaderLogo'
import Footer from '../components/Footer'
export default {
  head: {
    title: '用户登录',
    link: [
      {rel:'stylesheet',href:'style/login.css'}
    ],
    script: [
    ]
  },
  components : {
    TopNav,
    HeaderLogo,
    Footer
  },

}
</script>

<style>

</style>
4.8.2分析

在这里插入图片描述

4.8.3验证码:接口

http://localhost:10010/web-service/verifycode?username=jack

4.8.4验证码:生成与显示

  • 步骤一:后端生产验证码,并将用户保存Redis
  • 存放redis中验证码key格式:“login” + 用户名
package com.czxy.changgou4.controller;

import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;

import javax.annotation.Resource;
import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletResponse;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.Random;
import java.util.concurrent.TimeUnit;

/**
 * @author 桐叔
 * @email liangtong@itcast.cn
 */
@Controller
@RequestMapping("/verifycode")
public class VerifyCodeController {

    @Resource
    private StringRedisTemplate stringRedisTemplate;

    @GetMapping
    public void verifyCode(String username , HttpServletResponse response ) throws IOException {

        //字体只显示大写,去掉了1,0,i,o几个容易混淆的字符
        String VERIFY_CODES = "23456789ABCDEFGHJKLMNPQRSTUVWXYZ";

        int IMG_WIDTH = 72;
        int IMG_HEIGTH = 27;
        Random random = new Random();
        //创建图片
        BufferedImage image = new BufferedImage(IMG_WIDTH, IMG_HEIGTH, BufferedImage.TYPE_INT_RGB);
        //画板
        Graphics g = image.getGraphics();
        //填充背景
        g.setColor(Color.WHITE);
        g.fillRect(1,1,IMG_WIDTH-2,IMG_HEIGTH-2);

        g.setFont(new Font("楷体", Font.BOLD,25));

        StringBuilder sb = new StringBuilder();
        //写字
        for(int i = 1 ; i <= 4 ; i ++){
            //随机颜色
            g.setColor(new Color(random.nextInt(255),random.nextInt(255),random.nextInt(255)));
            int len = random.nextInt(VERIFY_CODES.length());
            String str = VERIFY_CODES.substring(len,len+1);
            sb.append(str);
            g.drawString(str, IMG_WIDTH / 6 * i , 22 );
        }

        //将验证码存放到redis
        stringRedisTemplate.opsForValue().set( "login" + username , sb.toString() , 1 , TimeUnit.HOURS);


        // 生成随机干扰线
        for (int i = 0; i < 30; i++) {
            //随机颜色
            g.setColor(new Color(random.nextInt(255),random.nextInt(255),random.nextInt(255)));
            int x = random.nextInt(IMG_WIDTH - 1);
            int y = random.nextInt(IMG_HEIGTH - 1);
            int x1 = random.nextInt(12) + 1;
            int y1 = random.nextInt(6) + 1;
            g.drawLine(x, y, x - x1, y - y1);
        }

        //响应到浏览器
        ImageIO.write(image,"jpeg", response.getOutputStream());

    }
}
  • 步骤二:点击“换一张”显示验证码
  • 默认不显示验证码
  • 点击“换一张”获得验证码
    在这里插入图片描述
<template>
  <div>
    <TopNav></TopNav>
    <div style="clear:both;"></div>
    <HeaderLogo></HeaderLogo>
    <div style="clear:both;"></div>
    <!-- 正文 -->
    <!-- 登录主体部分start -->
    <div class="login w990 bc mt10">
      <div class="login_hd">
        <h2>用户登录</h2>
        <b></b>
      </div>
      <div class="login_bd">
        <div class="login_form fl">
          <form action="" method="post">
            <ul>
              <li>
                <label for="">用户名:</label>
                <input type="text" class="txt" name="username" v-model="user.username" />
              </li>
              <li>
                <label for="">密码:</label>
                <input type="password" class="txt" name="password" v-model="user.password" />
                <a href="">忘记密码?</a>
              </li>
              <li class="checkcode">
                <label for="">验证码:</label>
                <input type="text"  name="checkcode" />
                <!-- <img src="images/checkcode1.jpg" alt="" /> -->
                <img :src="imgSrc" alt="" />
                <span>看不清?<a href="" @click.prevent="changeVerifyCode">换一张</a></span>
              </li>
              <li v-if="errorMsg != ''">
                <label for="">&nbsp;</label>
                <span style="color: #ff5b5b">{{errorMsg}}</span>
              </li>
              <li>
                <label for="">&nbsp;</label>
                <input type="checkbox" class="chb"  /> 保存登录信息
              </li>
              <li>
                <label for="">&nbsp;</label>
                <input type="submit" value="" class="login_btn" />
              </li>
            </ul>
          </form>

          <div class="coagent mt15">
            <dl>
              <dt>使用合作网站登录商城:</dt>
              <dd class="qq"><a href=""><span></span>QQ</a></dd>
              <dd class="weibo"><a href=""><span></span>新浪微博</a></dd>
              <dd class="yi"><a href=""><span></span>网易</a></dd>
              <dd class="renren"><a href=""><span></span>人人</a></dd>
              <dd class="qihu"><a href=""><span></span>奇虎360</a></dd>
              <dd class=""><a href=""><span></span>百度</a></dd>
              <dd class="douban"><a href=""><span></span>豆瓣</a></dd>
            </dl>
          </div>
        </div>

        <div class="guide fl">
          <h3>还不是商城用户</h3>
          <p>现在免费注册成为商城用户,便能立刻享受便宜又放心的购物乐趣,心动不如行动,赶紧加入吧!</p>

          <a href="regist.html" class="reg_btn">免费注册 >></a>
        </div>

      </div>
    </div>
    <!-- 登录主体部分end -->
    <div style="clear:both;"></div>
    <Footer></Footer>
  </div>
</template>

<script>
import TopNav from '../components/TopNav'
import HeaderLogo from '../components/HeaderLogo'
import Footer from '../components/Footer'
export default {
  head: {
    title: '用户登录',
    link: [
      {rel:'stylesheet',href:'style/login.css'}
    ],
    script: [
    ]
  },
  components : {
    TopNav,
    HeaderLogo,
    Footer
  },
  data() {
    return {
      imgSrc:'',
      errorMsg: '',
      user: {

      }
    }
  },
  methods: {
    changeVerifyCode() {
      if( this.user.username ) {
        this.imgSrc = `http://localhost:10010/web-service/verifycode?t=${new Date().getTime()}&username=${this.user.username }`
      } else {
        this.errorMsg = '用户名不能为空'
      }
    }
  },
  watch: {
    'user' : {
      handler(v) {
        if(v) {
          //如果user数据发生改变,修改提示信息
          this.errorMsg = ''
        }
      },
      deep: true
    }
  },

}
</script>

<style>

</style>

4.8.5通过用户名查询:接口

http://localhost:10010/web-service/user/findByUsername

4.8.6通过用户名查询:实现

  • 修改UserController,添加 findByUsername函数
/**
 * 通过用户名查询
 * @param user
 * @return 返回用户对象
 */
@PostMapping("/findByUsername")
public User findByUsername(@RequestBody User user){
    //查询用户
    User findUser = userService.findByUsername( user.getUsername() );
    return findUser;
}

4.8.7认证服务:构建项目(changgou4-service-auth)

  • 步骤一:构建项目

  • 步骤二:创建pom.xml文件

<dependencies>
    <!--自定义项目-->
    <dependency>
        <groupId>com.czxy.changgou</groupId>
        <artifactId>changgou4_common_auth</artifactId>
    </dependency>

    <!--web起步依赖-->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>

    <!-- nacos 客户端 -->
    <dependency>
        <groupId>com.alibaba.nacos</groupId>
        <artifactId>nacos-client</artifactId>
    </dependency>

    <!-- nacos 服务发现 -->
    <dependency>
        <groupId>com.alibaba.cloud</groupId>
        <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
    </dependency>
    <!--redis-->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-redis</artifactId>
    </dependency>
    <dependency>
        <groupId>redis.clients</groupId>
        <artifactId>jedis</artifactId>
    </dependency>
    <!--swagger2-->
    <dependency>
        <groupId>io.springfox</groupId>
        <artifactId>springfox-swagger2</artifactId>
    </dependency>
    <dependency>
        <groupId>io.springfox</groupId>
        <artifactId>springfox-swagger-ui</artifactId>
    </dependency>
</dependencies>
  • 步骤三:创建yml文件
server:
  port: 8085
spring:
  application:
    name: auth-service
  cloud:
    nacos:
      discovery:
        server-addr: 127.0.0.1:8848   #nacos服务地址

sc:
  jwt:
    secret: sc@Login(Auth}*^31)&czxy% # 登录校验的密钥
    pubKeyPath: D:/rsa/rsa.pub # 公钥地址
    priKeyPath: D:/rsa/rsa.pri # 私钥地址
    expire: 360 # 过期时间,单位分钟
  • 步骤四:配置启动类
package com.czxy.changgou4;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.openfeign.EnableFeignClients;

/**
 * @author 桐叔
 * @email liangtong@itcast.cn
 */
@SpringBootApplication
@EnableDiscoveryClient
@EnableFeignClients
public class CGAuthServiceApplication {
    public static void main(String[] args) {
        SpringApplication.run(CGAuthServiceApplication.class, args);
    }
}
  • 步骤五:配置类
    在这里插入图片描述

4.8.8认证服务:用户登录后端

  • 步骤一:创建AuthUser 封装对象(与User比较,缺数据库相关注解)
package com.czxy.changgou4.domain;

import lombok.Data;

import java.util.Date;

/**
 * @author 桐叔
 * @email liangtong@itcast.cn
 */
@Data
public class AuthUser {
    private Long id;

    private String username;

    private String password;

    private String face;

    private Integer expriece;

    private String email;

    private String mobile;

    private Date createdAt;

    private Date updatedAt;

    private String code;

    private String password_confirm;
}
  • 步骤二:创建UserFeign,完成远程用户查询功能
package com.czxy.changgou4.feign;

import com.czxy.changgou4.domain.AuthUser;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;

/**
 * @author 桐叔
 * @email liangtong@itcast.cn
 */
@FeignClient(value = "web-service",path="/user")
public interface UserFeign {

    @PostMapping("/findByUsername")
    public AuthUser findByUsername(@RequestBody AuthUser user);

}
  • 步骤三:创建AuthService接口,编写登录方法 login()
package com.czxy.changgou4.service;

import com.czxy.changgou4.domain.AuthUser;

/**
 * @author 桐叔
 * @email liangtong@itcast.cn
 */
public interface AuthService {

    /**
     * 用户登录
     * @param user
     * @return
     */
    public AuthUser login(AuthUser user ) ;
}
  • 步骤四:创建AuthService实现类,并通过BCrypt校验密码
package com.czxy.changgou4.service.impl;

import com.czxy.changgou4.domain.AuthUser;
import com.czxy.changgou4.feign.UserFeign;
import com.czxy.changgou4.service.AuthService;
import com.czxy.changgou4.utils.BCrypt;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;

/**
 * @author 桐叔
 * @email liangtong@itcast.cn
 */
@Service
public class AuthServiceImpl implements AuthService {
    @Resource
    private UserFeign userFeign;

    /**
     * 用户登录
     * @param user
     * @return
     */
    public AuthUser login(AuthUser user ) {
        //远程查询用户
        AuthUser findUser = userFeign.findByUsername(user);
        if(findUser == null) {
            return null;
        }
        //校验密码是否正确
        boolean checkpw = BCrypt.checkpw( user.getPassword(), findUser.getPassword());
        if(checkpw){
            return findUser;
        }
        return null;
    }

}
  • 步骤五:创建AuthController,添加login方法
  • redis中登录验证码和用户输入的验证码进行匹配
package com.czxy.changgou4.controller;

/**
 * @author 桐叔
 * @email liangtong@itcast.cn
 */

import com.czxy.changgou4.domain.AuthUser;
import com.czxy.changgou4.service.AuthService;
import com.czxy.changgou4.vo.BaseResult;
import org.springframework.data.redis.core.StringRedisTemplate;
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;

import javax.annotation.Resource;

/**
 * Created by liangtong.
 */
@RestController
@RequestMapping("/auth")
public class AuthController {

    @Resource
    private AuthService authService;

    @Resource
    private StringRedisTemplate stringRedisTemplate;

    @PostMapping("/login")
    public BaseResult login(@RequestBody AuthUser user){
        //校验验证码--使用后删除
        String redisCode = stringRedisTemplate.opsForValue().get( "login" + user.getUsername() );
        stringRedisTemplate.delete( "login" + user.getUsername() );
        if(redisCode == null) {
            return BaseResult.error("验证码无效");
        }
        if(! redisCode.equalsIgnoreCase(user.getCode())) {
            return BaseResult.error("验证码错误");
        }
        //登录
        AuthUser loginUser = authService.login(user);
        if(loginUser != null ) {
            return BaseResult.ok("登录成功").append("loginUser",loginUser);
        } else {
            return BaseResult.error("用户名或密码不匹配");
        }
    }
}

4.8.9认证服务:用户登录前端

  • 步骤一:修改apiclient.js,添加login函数
 //登录
  login : ( user )=> {
    return axios.post('/auth-service/auth/login', user )
  }
  • 步骤二:修改Login.vue,给验证码绑定变量
<li class="checkcode">
                <label for="">验证码:</label>
                <input type="text"  name="checkcode" v-model="user.code" />
                <!-- <img src="images/checkcode1.jpg" alt="" /> -->
  • 步骤三:修改Login.vue,给提交按钮绑定事件
 <li>
         <label for="">&nbsp;</label>
         <input type="submit" value="" @click.prevent="loginFn" class="login_btn" />
 </li>
  • 步骤四:编写loginFn完成登录功能
  • 登录成功,跳转到首页
  • 登录失败,给出提示
 async loginFn() {
      let { data } = await this.$request.login( this.user )
      if( data.code == 20000) {
        //成功
        sessionStorage.setItem('user' , JSON.stringify(data.other.loginUser) )
        //跳转到首页
        this.$router.push('/')
      } else {
        this.errorMsg = data.message
      }
    }
  • 步骤五:创建首页 ~/pages/index.vue,
    在这里插入图片描述
<template>
  <div>
    <TopNav></TopNav>
  </div>
</template>

<script>
import TopNav from '../components/TopNav'

export default {
  head: {
    title: '首页',
    link: [
      {rel:'stylesheet',href:'style/index.css'},
      {rel:'stylesheet',href:'style/bottomnav.css'}
    ],
    script: [
      { type: 'text/javascript', src: 'js/header.js' },
      { type: 'text/javascript', src: 'js/index.js' },
    ]
  },
  components : {
    TopNav,
  },
}
</script>

<style>

</style>
  • 步骤六:重命名静态页面 ~/static/index.html 为 ~/static/home.html

4.8.10修改 TopNav.vue 组件

  • 完善导航条,根据vuex中的数据,显示不同内容

  • 步骤一:创建 ~/store/index.js ,并编写vuex内容
    在这里插入图片描述

export const state = () => ({
  user: null
})

//通用设置
export const mutations = {
  setData( state , obj) {
    state[obj.key] = obj.value
  }
}
  • 步骤二:页面登录成功,将用户信息保存到vuex中
    在这里插入图片描述
// 将用户信息保存到vuex中
this.$store.commit('setData', {key:'user',value: data.data })
  • 步骤三:修改顶部导航TopNav.vue
  • 从vuex中的数据
    在这里插入图片描述
<template>
  <!-- 顶部导航 start -->
  <div class="topnav">
    <div class="topnav_bd w990 bc">
      <div class="topnav_left">

      </div>
      <div class="topnav_right fr">
        <ul>
          <li v-if="user != null">您好,{{user.username}} 欢迎来到畅购! <a href="" @click.prevent="logout">退出</a></li>
          <li v-if="user != null" class="line">|</li>
          <li v-if="user == null">[<a href="/login">登录</a>] [<a href="/register">免费注册</a>] </li>
          <li v-if="user == null" class="line">|</li>
          <li v-if="user != null">我的订单</li>
          <li v-if="user != null" class="line">|</li>
          <li>客户服务</li>

        </ul>
      </div>
    </div>
  </div>
  <!-- 顶部导航 end -->
</template>

<script>
import {mapState,mapMutations} from 'vuex'
export default {
  mounted() {
    let userStr = sessionStorage.getItem('user')
    if(userStr){
      // 将string数据转换object,并填充到vuex中
      this.setData({key:'user',value: JSON.parse(userStr)})
    }
  },
  methods: {
    logout() {
      sessionStorage.removeItem('user')
      sessionStorage.removeItem('token')
      //设置vuex中的数据为空
      this.setData({key:'user',value: null })
      this.$router.push('/login')
    },
    ...mapMutations(['setData'])
  },
  computed: {
    ...mapState(['user'])
  },
}
</script>

<style>

</style>

4.8.11vuex刷新数据丢失

  • 刷新操作:
  • 点击刷新按钮
  • 点击回退按钮
  • 地址栏直接输入地址
  • 现象:
  • vuex在刷新操作后,数据丢失了
  • 解决方案
    方案1:不是公共组件:页面在pages目录下,可以nuxt.js提供 fetch进行操作。
    方案2:是公共组件:组件在components目录下,借助第三方进行存储(cookie、localStorage、sessionStorage)
  • 具体操作:
    如果vuex中没有数据,使用sessionStorage的数据填充vuex。
    修改TopNav.vue页面
<!-- 顶部导航 start -->
  <div class="topnav">
    <div class="topnav_bd w990 bc">
      <div class="topnav_left">

      </div>
      <div class="topnav_right fr">
        <ul>
          <li v-if="user!=null">您好,{{user.username}}欢迎来到畅购!
          </li>
          <li v-if="user==null">
            [<nuxt-link to="/Login">登录</nuxt-link>]
          </li>
          <li v-if="user==null">
            [<nuxt-link to="/Register">免费注册</nuxt-link>]
          </li>
          <li v-if="user!=null">
            [<nuxt-link to="/Login">退出</nuxt-link>]
          </li>
          <li v-if="user!=null" class="line">|</li>
          <li v-if="user!=null">我的订单</li>
          <li class="line">|</li>
          <li>客户服务</li>
        </ul>
      </div>
    </div>
  </div>
  <!-- 顶部导航 end -->
</template>

<script>
import {mapState, mapMutations} from 'vuex'
export default {
  computed: { //计算属性整合vuex
    // user() {
    //   return this.$store.state.user
    // }
    ...mapState(['user'])
  },
  mounted() {
    // 从sessionStorage获得信息,如果存在,直接添加vuex中
    let userStr = sessionStorage.getItem('user')
    if(userStr) {
      let user = JSON.parse(userStr)
      //将数据存放到vuex中
      this.setData({key:'user',value: user })
    }
  },
  methods: {
    ...mapMutations(['setData']),

  },
}
</script>

<style>

</style>
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 2019年黑马项目-畅购商城springcloud微服务实战是一门以实战为主的课程,旨在通过项目实践的方式,帮助学员深入理解和掌握SpringCloud微服务架构以及相关技术的应用。 课程的主要内容包括搭建基础的微服务架构、使用SpringCloud构建服务注册与发现、实现服务间的负载均衡、实现分布式配置中心、服务间的用与容错处理、使用网关统一接入服务等。通过这些实战练习,学员不仅能够熟悉SpringCloud架构与组件,还能够了解微服务架构下的常见问题与解决方案。 畅购商城项目是一个典型的电商应用,通过实现该项目,学员可以接触到真实的业务场景与需求,并能够将所学知识应用到实际项目中。课程中通过模块化的方式逐步完善商城的功能,包括用户注册登录、商品浏览、购物车管理、订单生成与支付等。通过这些实践,学员除了掌握SpringCloud微服务的开发技术,还能够了解和掌握电商项目的开发流程和注意事项。 该课程的目标是让学员通过实战项目,全面了解和掌握SpringCloud微服务架构的设计与开发,在此基础上能够独立完成具有较高要求的微服务项目。通过参与实战项目的过程,学员还能够提升团队协作能力、解决问题的能力以及项目管理能力。 通过这门课程的学习,学员将会对SpringCloud微服务架构有更深入的理解,并能够将这些知识应用到实际项目中,提高自己在微服务开发领域的竞争力。 ### 回答2: 2019年黑马项目-畅购商城springcloud微服务实战是一个基于springcloud微服务架构的商城项目。该项目的目标是通过运用微服务的理念和技术,构建一个高可用、可扩展的商城系统。 在该项目中,使用了springcloud的多个组件,如Eureka注册中心、Feign负载均衡、Ribbon客户端负载均衡、Hystrix服务降级和容错、Zuul网关等。这些组件共同协作,实现了系统的弹性伸缩和高可用性。 畅购商城的功能包括商品展示、购物车、订单管理、支付、用户管理等。通过将这些功能拆分成独立的微服务,使得系统更加灵活和可维护。同时,使用分布式事务和消息队列来保障数据的一致性和可靠性。 在项目的开发过程中,采用了敏捷开发的方法,以迭代的方式进行开发和测试。通过使用Jenkins进行持续集成和部署,保证了代码的质量和系统的稳定性。 在项目的实战过程中,面临了许多挑战和困难,如微服务之间的通信、服务的负载均衡、服务的容错等。但通过团队的共同努力和不断的学习,最终成功地完成了该项目的开发和部署。 在该项目的实施过程中,不仅学到了springcloud微服务架构的相关知识和技术,还体会到了团队合作和解决问题的能力。该项目的成功实施,不仅为公司带来了商业价值,也提升了团队的技术水平和项目管理能力。 ### 回答3: 2019年黑马项目-畅购商城springcloud微服务实战是一个以Spring Cloud为基础的微服务项目。微服务架构是一种将应用拆分成多个小型服务的架构模式,这些服务可以独立开发、部署、扩展和管理。 畅购商城项目使用了Spring Cloud的一系列子项目,如Eureka、Ribbon、Feign、Hystrix、Zuul等,来实现各个微服务之间的通信、负载均衡、服务降级与熔断等功能。 在项目中,我们会通过Eureka来实现服务的注册与发现,每个微服务都会向Eureka注册自己的地址,其他微服务可以通过Eureka来发现并用这些服务。而Ribbon则负责实现客户端的负载均衡,可以轮询、随机、加权等方式分发请求。 Feign是一种声明式的HTTP客户端,它简化了服务间的用方式。我们只需编写接口,并通过注解来描述需要用的服务和方法,Feign会自动实现远程用。 Hystrix是一个容错机制的实现,可以通过断路器来实现服务的降级与熔断,当某个服务出现故障或超时时,Hystrix会快速响应并返回一个可控制的结果,从而保证系统的稳定性。 另外,Zuul作为微服务网关,可以实现请求的统一入口和路由转发,提高系统的安全性和性能。 通过这些Spring Cloud的组件,畅购商城项目可以实现高可用、容错、自动扩展等优质的微服务架构。 总之,2019年黑马项目-畅购商城springcloud微服务实战是一个基于Spring Cloud的微服务项目,通过使用Spring Cloud的各个子项目,可以实现微服务之间的通信、负载均衡、服务降级与熔断等功能,为项目的开发、部署和管理提供了便利。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值