庐山真面目之九微服务架构 NetCore 基于 Docker 基础镜像和挂载文件部署



一、简介

       我们在上一篇文章《庐山真面目之八微服务架构
NetCore 基于 Dockerfile 文件部署
》中介绍了,如何在Linux系统上的Docker容器中部署Net Core项目的第一种方法。当然,有些话忘记说了,今天我们补上。如果大家要想练习我们的例子,大家必须对Linux系统有所了解,对Linux的基础操作命令也要有使用经验,因为我踩了很多坑,伤心啊。在这个基础上,也要对Docker比较熟悉,Docker的操作命令也要比较熟悉,否则,真的就有些困难了。今天作为介绍把Net Core项目部署到Linux系统中的Docker容器中第二种方式,继续我们这个系列。这三种方式要这么详细的交代,是因为,在我以后的文章里,如果再有涉及项目的部署和迁移的话题,就不会写的这么详细了。也希望大家见谅和理解,因为我们每篇文章都要突出文章的主题,而且每篇文章解决一个问题,否则,喧宾夺主就不好了。看过我文章的人会知道,我的文章会有重复的部分,这样做也是为了照顾读者,每篇文章都是独立的,让大家看的清楚和明白,避免在多篇文章之间切换,不是为了凑字数。



    1、说明

          今天这篇文章很简单,就是介绍把Net
Core 项目部署到Linux环境的Docker容器中的第二种方式。当然了,对于高手来说,这些都是微不足道的,但是对于新手或者说刚入门的人来说可能是有帮助的,所以说,高手就不用冷嘲热讽,如果想发表自己的高论,也欢迎不灵赐教。特别说明,这里的所有代码都经过测试,所以大家可以放心使用,但是实际情况可能不一样,结果也未必一样。



    2、开发环境

          
以下就是开发环境,不用多说,都很简单,一看就知道。

         (1)、开发工具:Visual
Studio 2019

         (2)、开发语言:C#

         (3)、开发平台:Net
Core3.1,跨平台。

         (4)、操作系统:Linux(CentOS 7)。

         (5)、虚拟容器:Docker
19.03.13

         (6)、文件上传:SSH
Secure File Transfer Client或者XFTP

         (7)、客 户 端:SSH Secure Shell
Client或者XShell

         (8)、虚拟系统:VMware
Workstation Pro 14.1.3

二、Docker容器技术的简介

   

      



    1
、Docker简介

            Docker 是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的Linux机器或Windows 机器上,也可以实现虚拟化,容器是完全使用沙箱机制,相互之间不会有任何接口。

            Docker是Docker.Lnc公司开源的一个基于LXC技术之上搭建的Container容器引擎,源代码托管在Github上,基于Go语言并遵从Apache2.0协议开源。

            Docker属于Linux容器的一种封装,提供简单易用的容器使用接口。

            Docker将应用程序与该程序的依赖,打包在一个文件里面。运行这个文件,就会生成一个虚拟容器。程序在这个虚拟容器里运行,就好像在真实的物理机上运行一样。有了Docker,就不用担心环境问题。

            总体来说,Docker的接口相当简单,用户可以方便地创建和使用容器,把自己的应用放入容器。容器还可以进行版本管理、复制、分享、修改,就像管理普通的代码一样。

      

             一个完整的Docker有以下几个部分组成:

                Docker Client客户端:可以输入各种命令操作Docker镜像、容器。

                Docker Daemon守护进程:Docker的服务器端,完成客户端的请求和命令。

                Docker Image镜像:镜像就是容器实例的模板,根据该模板生成容器实例。

                Docker Container容器:根据镜像文件生成的容器实例,没有镜像,无法生成容器。



              Docker结构组成:

               



    2、基础命令

          (1)、安装工具包

                  命令:yum install -y
yum-utils

             

          (2)、设置镜像仓库

                  命令:阿里云:$ yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo

                   清华大学源:$yum-config-manager --add-repo  https://mirrors.tuna.tsinghua.edu.cn/docker-ce/linux/centos/docker-ce.repo

         

          (3)、安装启动 docker

                  命令:



          (4)、停止正在运行的容器

                  命令:docker stop 容器名称/容器ID



          (5)、启动停止的容器:

                  命令:docker start 容器名称/容器ID



          (6)、查询创建的容器:

                  命令:docker-compose ps

             

          (7)、删除指定容器:

                  命令:docker rm 容器名称/容器ID



          (8)、删除所有容器:

                  命令:docker rm $(docker
ps -aq)



          (9)、查询所有镜像:

                  命令:docker ps –a



          (10)、删除镜像:

                   命令:docker rmi 镜像名称/镜像ID



          (11)、删除所有镜像:

                   命令:docker rmi $(docker images -q)



          (12)、docker-compose命令详细参考:

                   命令:docker-compose –h



          (13)、停止并删除所有运行的容器实例:

                   命令:docker stop
$(docker ps -q) & docker rm $(docker ps -aq)



          (14)、查看日志:

                   命令:docker logs 容器id/容器名称



          (15)、查看统计:

                   命令:docker stats 容器id/容器名称



          (16)、docker 以别名 形式运行指定镜像

                   命令:docker run -itd -p
host:container --name 别名
镜像id/镜像名称



            (17)、限制镜像使用的内存
-m:

                   命令:docker run -itd -p
hostPort:containerPort --name 别名 -m 200m 镜像id/镜像名称

          

          (18)、限制镜像使用的 cpu
数目 --cpus。:

                   命令:docker run -itd -p
hostPort:containerPort --name 别名 --cpus 1 镜像id/镜像名称



          (19)、进入指定的容器

                   命令:$Docker exec -it 容器ID|容器名称
/bin/bash



                  

三、Docker容器和虚拟机的区别

   
      我在这里只是简单的介绍一下Docker容器和虚拟机的区别,给大家一个感性的认识,如果大家想去了解更详细的内容,自己去网上学习吧,内容很多,比我写的要好很多。技术来源于生活,又高于生活,所以,我们学习的技术,是可以和生活的一些事物做类比的。就拿虚拟技术来说,它的发展历程,和我们居住条件的发展有些类似。



    1、虚拟技术发展史



          (1)、单独物理机【独栋别墅】

                   

                   有钱人就住自己的大别墅,有自己的草坪,独立的花园,漂亮的游泳池,当然,还有很多根本没时间住的房间,对于个人来说,当然很舒服,也是我们每个人向往的生活。但是,对于土地资源来说,利用率不高。对于网络环境来说,也是同样的道理。刚开始的时候,人们的系统都是部署在自己购买的独立的物理机中,这样的物理机有着一套完整的操作系统,安全系统,网络环境,还有很多用不到的功能,什么都有自己的独立的一套,完全没有重用的概念。每套系统就对应着这么一套完整的东西,包括硬件、软件和网络等资源,大系统是这样,小系统也是这样,这样下去肯定不行。



          (2)、虚拟机时代【高楼社区】

                   

                   虚拟技术发展的第二阶段就是虚拟机时代,这个时代,就和我们居住的社区一样,人们通过在城市买房子居住在高档社区里,这个时候比第一个阶段要好很多,可以共享很多,比如:门禁、保安、地基、物业等公共服务。但是,每个家庭还是一个独立的单元,有自己独立的卫生间,独立卧室,厨房、餐厅和网络等。这个时代的网络环境、服务器技术得到了高速发展,人们开始注意资源的利用率。虚拟机的技术也得到了很好的发展和使用,我们可以在一台大型机器上部署多台虚拟机,这个大型机器,就像我们居住的小区楼房,这样一来,提高了资源利用率,可以共用硬件、网络和其他一些基础设施,但是每个虚拟机内部还有一套完整的操作系统,服务组件等,这个时候的虚拟机使用起来,感觉和使用物理机的差别不大。



          (3)、Docker容器【胶囊公寓】

                  

                  虚拟技术发展的第三个阶段就是极简模式,也可以叫“胶囊公寓”模式。胶囊公寓这种居住方式在寸土寸金的大城市,比如:日本的东京,我国的香港还挺普遍的。在这样的公寓里,只提供一个人休息、睡觉的最基本的地方和功能,其他多余的功能一概没有,那个时候除了床、被子和灯光是你可以控制的,其他都是公用的。Docker容器技术就是这个时代的产物,为了提高资源的利用率,开始对虚拟机进行瘦身,进而诞生了容器技术,容器内部不在包含完整的操作系统,是一个极简版本的操作系统,能运行软件所必须的系统环境,除了精简的系统外,就是程序运行所依赖的必须环境,再者就是要部署的程序了。



    2、二者区别,看图理解吧!

        
           

             虚拟机就是我们社区的高楼,容器就是“胶囊公寓”

                  



    3、容器能给我们带来什么呢?

       

        

四、Net Core项目基于Docker 容器的部署方式



       今天,我们就开始介绍将Net Core项目部署到Linux系统上的Docker容器中的第二种方法。开始之前,说明一下,因为我们今天要将系统部署到Docker容器里,所以,在开始之前,必须安装好了Docker容器,我当前安装的版本是:19.03.13,如果你登录了Linux系统(CentOS7),可以通过输入命令:Docker --version检查是否安装了Docker,如果没有安装,提示:没有这个命令(command not found),如果安装了,会显示具体的版本号:Docker version 19.03.13,build 4484c46d9d。还要说明一点,Docker的版本尽量要最新,最起码要在18或者以上,否则会出现一些问题,我就是遇到了问题,最后升级后才解决的,如果想升级自己的Docker,可以查看《如何将Docker升级到最新版本》。
 

    今天我们开始创建项目镜像和挂载文件,开始之前,我们先创建测试项目。



    1、搭建测试项目。



             (1)、PatrickLiu.MicroService.Interfaces(NetCore类库项目),定义抽象接口层,代码很简单,因为它不是重点,重点是框架。

              

                         

            

                   

                      样例代码:

 1 using PatrickLiu.MicroService.Models;
2 using System.Collections.Generic;
3
4 namespace PatrickLiu.MicroService.Interfaces
5 {
6 /// <summary>
7 /// 用户服务的接口定义。
8 /// </summary>
9 public interface IUserService
10 {
11 /// <summary>
12 /// 查找指定主键的用户实例对象。
13 /// </summary>
14 /// <param name="id">用户的主键。</param>
15 /// <returns>返回查找到的用户实例对象。</returns>
16 User FindUser(int id);
17
18 /// <summary>
19 /// 获取所有用户的实例集合。
20 /// </summary>
21 /// <returns>返回所有的用户实例。</returns>
22 IEnumerable<User> UserAll();
23 }
24 }

      (2)、PatrickLiu.MicroService.Models(NetCore类库项目),定义用于传递数据的实体模型,代码很简单,因为它不是重点,重点是框架。

              

            

            



                       样例代码:

 1 using System;
2
3 namespace PatrickLiu.MicroService.Models
4 {
5 /// <summary>
6 /// 用户模型。
7 /// </summary>
8 public class User
9 {
10 /// <summary>
11 /// 获取或者设置用户主键。
12 /// </summary>
13 public int ID { get; set; }
14
15 /// <summary>
16 /// 获取或者设置用户姓名。
17 /// </summary>
18 public string Name { get; set; }
19
20 /// <summary>
21 /// 获取或者设置用户账号名称。
22 /// </summary>
23 public string Account { get; set; }
24
25 /// <summary>
26 /// 获取或者设置用户密码。
27 /// </summary>
28 public string Password { get; set; }
29
30 /// <summary>
31 /// 获取或者设置用户的电子邮箱地址。
32 /// </summary>
33 public string Email { get; set; }
34
35 /// <summary>
36 /// 获取或者设置用户角色。
37 /// </summary>
38 public string Role { get; set; }
39
40 /// <summary>
41 /// 获取或者设置用户的登录时间。
42 /// </summary>
43 public DateTime LoginTime { get; set; }
44 }
45 }

      (3)、PatrickLiu.MicroService.Services(NetCore类库项目),定义实现接口的服务层,代码很简单,因为它不是重点,重点是框架。

             

            

                       



                      样例代码:

 1 using PatrickLiu.MicroService.Interfaces;
2 using PatrickLiu.MicroService.Models;
3 using System;
4 using System.Collections.Generic;
5 using System.Linq;
6
7 namespace PatrickLiu.MicroService.Services
8 {
9 /// <summary>
10 /// 实现用户服务接口的实现类型。
11 /// </summary>
12 public class UserService : IUserService
13 {
14 private IList<User> dataList;
15
16 /// <summary>
17 /// 初始化类型的实例
18 /// </summary>
19 public UserService()
20 {
21 dataList = new List<User>()
22 { new User {ID=1,Name="黄飞鸿",Account="HuangFeiHong",Password="HuangFeiHong123456",Email="huangFeiHong@sina.com", Role="Admin", LoginTime=DateTime.Now },
23 new User {ID=2,Name="洪熙官",Account="HongXiGuan",Password="HongXiGuan54667",Email="HongXiGuan@sina.com", Role="Admin", LoginTime=DateTime.Now.AddDays(-5) },
24 new User {ID=3,Name="方世玉",Account="FangShiYu",Password="FangShiYu112233",Email="fangShiYu@163.com", Role="Admin", LoginTime=DateTime.Now.AddDays(-30) },
25 new User {ID=4,Name="苗翠花",Account="MiaoCuiHua",Password="MiaoCuiHua887766",Email="miaoCuiHua@sohu.com", Role="Admin", LoginTime=DateTime.Now.AddDays(-90) },
26 new User {ID=5,Name="严咏春",Account="YanYongChun",Password="YanYongChun09392",Email="yanYongChun@263.com", Role="Admin", LoginTime=DateTime.Now.AddMinutes(-50) }};
27 }
28
29 /// <summary>
30 /// 查找指定主键的用户实例对象。
31 /// </summary>
32 /// <param name="id">用户的主键。</param>
33 /// <returns>返回查找到的用户实例对象。</returns>
34 public User FindUser(int id)
35 {
36 return dataList.FirstOrDefault(user => user.ID == id);
37 }
38
39 /// <summary>
40 /// 获取所有用户的实例集合。
41 /// </summary>
42 /// <returns>返回所有的用户实例。</returns>
43 public IEnumerable<User> UserAll()
44 {
45 return dataList;
46 }
47 }
48 }

      (4)、PatrickLiu.MicroService.ServiceInstance(Asp.Net Core
WebAPI项目),对外提供业务功能WebApi项目,该项目必须引入其他关联项目:


                         PatrickLiu.MicroService.Interfaces

                         PatrickLiu.MicroService.Models

                         PatrickLiu.MicroService.Services



                         

    

                         样例代码:

                         

  1 using System;
2 using System.Collections.Generic;
3 using System.Linq;
4 using System.Threading;
5 using Microsoft.AspNetCore.Authorization;
6 using Microsoft.AspNetCore.Mvc;
7 using Microsoft.Extensions.Configuration;
8 using Microsoft.Extensions.Logging;
9 using PatrickLiu.MicroService.Interfaces;
10 using PatrickLiu.MicroService.Models;
11
12 namespace PatrickLiu.MicroService.ServiceInstance.Controllers
13 {
14 /// <summary>
15 /// 用户的 API 类型。
16 /// </summary>
17 [Route("api/[controller]")]
18 [ApiController]
19 public class UsersController : ControllerBase
20 {
21 #region 私有字段
22
23 private readonly ILogger<UsersController> _logger;
24 private readonly IUserService _userService;
25 private IConfiguration _configuration;
26
27 #endregion
28
29 #region 构造函数
30
31 /// <summary>
32 /// 初始化该类型的新实例。
33 /// </summary>
34 /// <param name="logger">日志记录器。</param>
35 /// <param name="userService">用户服务接口。</param>
36 /// <param name="configuration">配置服务。</param>
37 public UsersController(ILogger<UsersController> logger, IUserService userService, IConfiguration configuration)
38 {
39 _logger = logger;
40 _userService = userService;
41 _configuration = configuration;
42 }
43
44 #endregion
45
46 #region 实例方法
47
48 /// <summary>
49 /// 获取一条记录
50 /// </summary>
51 /// <param name="id"></param>
52 /// <returns></returns>
53 [HttpGet]
54 [Route("Get")]
55 public User Get(int id)
56 {
57 return _userService.FindUser(id);
58 }
59
60 /// <summary>
61 /// 获取所有记录。
62 /// </summary>
63 /// <returns></returns>
64 [HttpGet]
65 [Route("All")]
66 //[Authorize]
67 public IEnumerable<User> Get()
68 {
69 Console.WriteLine($"This is UsersController {this._configuration["port"]} Invoke");
70
71 return this._userService.UserAll().Select((user => new User
72 {
73 ID = user.ID,
74 Name = user.Name,
75 Account = user.Account,
76 Password = user.Password,
77 Email = user.Email,
78 Role = $"{this._configuration["ip"]}:{this._configuration["port"]}",
79 LoginTime = user.LoginTime
80 })); ;
81 }
82
83 /// <summary>
84 /// 超时处理
85 /// </summary>
86 /// <returns></returns>
87 [HttpGet]
88 [Route("Timeout")]
89 public IEnumerable<User> Timeout()
90 {
91 Console.WriteLine($"This is Timeout Start");
92 //超时设置。
93 Thread.Sleep(3000);
94
95 Console.WriteLine($"This is Timeout End");
96
97 return this._userService.UserAll().Select((user => new User
98 {
99 ID = user.ID,
100 Name = user.Name,
101 Account = user.Account,
102 Password = user.Password,
103 Email = user.Email,
104 Role = $"{this._configuration["ip"]}:{this._configuration["port"]}",
105 LoginTime = user.LoginTime
106 })); ;
107 }
108
109 #endregion
110 }
111 }
1         /// <summary>
2 /// 配置注入容器的实例。
3 /// </summary>
4 /// <param name="services"></param>
5 public void ConfigureServices(IServiceCollection services)
6 {
7 services.AddSingleton<IUserService, UserService>();
8 }

      Program.cs

1         public static void Main(string[] args)
2 {
3 new ConfigurationBuilder()
4 .SetBasePath(Directory.GetCurrentDirectory())
5 .AddCommandLine(args)//支持命令行
6 .Build();
7
8 CreateHostBuilder(args).Build().Run();
9 }

    2、发布项目。

             我们为了将Net Core项目部署到Linux(CentOS7)环境的Docker容器中去,先要发布我们的项目:PatrickLiu.MicroService.ServiceInstance,因此,我们就要在该项目上点击鼠标右键选择菜单【发布】。



               (1)、开始发布项目。

                       

               (2)、项目发布成功


                      



               (3)、发布后的项目文件。


                           



    3、生成Docker镜像文件。

             (1)、拷贝文件

                      项目文件必须发布成功,然后将发布成功的程序文件拷贝的Linux服务器上。

            

                      服务器路径:/root/testProject/second

            

             

                      Linux(CentOS7)服务器上的文件目录结构。

                      



             (2)、查看Linux服务器上的文件结构。

                      命令:ls –a

             

            



    4、生成容器实例。

            我们可以直接生成容器实例了。

             命令:docker run -d -p
8083:80 -v /root/testProject/second:/app 
--workdir /app mcr.microsoft.com/dotnet/core/aspnet dotnet  /app/PatrickLiu.MicroService.ServiceInstance.dll

               



    5、通过命令测试容器是否正常运行。

            命令:Docker ps –a



              



    6、通过浏览器访问来测试。

            容器启动正常,那我们就可以通过浏览器访问看看,我们先获取我们的地址。

             命令:ifconfig



               



             有了地址,我们访问:http://192.168.127.141:8083/api/users/all



               

五、结束语

  
     好了,今天就写到这里了。这个系列整理起来还是很费劲的,因为每个环节都要测试到,保证所写的代码都在测试环境中能运行的,但是累并快乐着。正所谓,不积跬步,无以至千里,每天进步一点点,加油。

庐山真面目之九微服务架构 NetCore 基于 Docker 基础镜像和挂载文件部署的更多相关文章

  1. 庐山真面目之八微服务架构 NetCore 基于 Dockerfile 文件部署

    庐山真面目之八微服务架构 NetCore 基于 Dockerfile 文件部署 一.简介      从今天开始,不出意外的话,以后所写的文章中所介绍项目的部署环境都应该会迁移到Linux环境上,而且是 ...

  2. 庐山真面目之十微服务架构 Net Core 基于 Docker 容器部署 Nginx 集群

    庐山真面目之十微服务架构 Net Core 基于 Docker 容器部署 Nginx 集群 一.简介      前面的两篇文章,我们已经介绍了Net Core项目基于Docker容器部署在Linux服 ...

  3. 庐山真面目之十一微服务架构手把手教你搭建基于Jenkins的企业级CI/CD环境

    庐山真面目之十一微服务架构手把手教你搭建基于Jenkins的企业级CI/CD环境 一.介绍 说起微服务架构来,有一个环节是少不了的,那就是CI/CD持续集成的环境.当然,搭建CI/CD环境的工具很多, ...

  4. 使用Redis为注册中心的Dubbo微服务架构(基于SpringBoot)

    title: 使用Redis为注册中心的Dubbo微服务架构(基于SpringBoot) date: 2019-07-30 14:06:29 categories: 架构 author: mrzhou ...

  5. 庐山真面目之二微服务架构NGINX版本实现

    一.简介          在上一篇文章<庐山真面目之微服务的简介和技术栈>中,我们已经探讨了微服务的来龙去脉,也说了想要实现微服务架构所需要的技术栈,今天我们开始实现一个微服务,当然这个 ...

  6. 微服务架构:基于微服务和Docker容器技术的PaaS云平台架构设计(微服务架构实施原理)

    版权声明:本文为博主原创文章,转载请注明出处,欢迎交流学习! 基于微服务架构和Docker容器技术的PaaS云平台建设目标是给我们的开发人员提供一套服务快速开发.部署.运维管理.持续开发持续集成的流程 ...

  7. 庐山真面目之十三微服务架构中如何在Docker上使用Redis缓存

    一.介绍     1.开始说明 在微服务器架构中,有一个组件是不能少的,那就是缓存组件.其实来说,缓存组件,这个叫法不是完全正确,因为除了缓存功能,它还能完成其他很多功能.我就不隐瞒了,今天我们要探讨 ...

  8. 第三代微服务架构:基于 Go 的博客微服务实战案例,支持分布式事务

    这是一个可一键部署在 Kubernetes-Istio 集群中的,基于 Golang 的博客微服务 Demo,支持分布式事务. 项目地址:https://github.com/jxlwqq/blog- ...

  9. 微服务架构 ------ Ubuntu下Docker的安装

    1.准备一个全新的Ubuntu环境 2.准备安装Docker及其依赖 apt-get update 更新数据源 apt-get -y install apt-transport-https ca-ce ...

随机推荐

  1. Golang 实现 Redis(7): Redis 集群与一致性 Hash

    本文是使用 golang 实现 redis 系列的第七篇, 将介绍如何将单点的缓存服务器扩展为分布式缓存.godis 集群的源码在Github:Godis/cluster 单台服务器的CPU和内存等资 ...

  2. Codeforces Round #677 (Div. 3) E、G题解

    E. Two Round Dances #圆排列 题目链接 题意 \(n\)(保证偶数)个人,要表演一个节目,这个节目包含两种圆形舞蹈,而每种圆形舞蹈恰好需要\(n/2\)个人,每个人只能跳一种圆形舞 ...

  3. Codeforces Round #672 (Div. 2) B. Rock and Lever题解(思维+位运算)

    题目链接 题目大意 给你一个长为n(n<=1e5)的数组,让你求有多少对a[i]和a[j] (i!=j)满足a[i]&a[j]>a[i]^a[j] 题目思路 这些有关位运算的题目肯 ...

  4. Mat使用详解

    背景 笔记中躺了很久的文章,今天用到Mat时发现之前写的内容还算清晰,分享出来; 如下所举例使用的dump文件是针对之前使用的ignite库溢出时的dump文件:关于ignite的概念此处不再叙述,本 ...

  5. CARDS主题 & 导航栏样式修改

    每个人对于主题样式的感觉是不一样的,譬如字体大小,间距,高宽,距离,颜色等,我们可以一定程度内很直观地去修改主题的某些样式. 首先,在浏览器中利用开发者工具进行调试,找到我们所要改动的那部分结构,写入 ...

  6. seata

    启动seataserver: 回滚日志: server日志: file模式的文件 整个过程如果观察数据库变化的话,会发现事务是先提交了的,出现异常之后由seata又回滚回去

  7. houdini 鱼眼相机

    http://mattebb.com/weblog/houdini-fisheye-camera/ 这个网站是有提供一个相机shader的,,如图是方形的,国内的用户,比较多是做球幕的小伙伴,圆形就行 ...

  8. 你的Idea还可用吗?不妨试试这个神器!

    @ 目录 一.STS安装 1.STS下载 2.STS安装 二.STS使用 1.STS配置JDK 2.STS配置Maven 3.使用STS创建SpringBoot项目 三.优化STS 1.主题美化 2. ...

  9. 第一次UML作业

    这个作业属于哪个课程 https://edu.cnblogs.com/campus/fzzcxy/2018SE2/ 这个作业要求在哪里 https://edu.cnblogs.com/campus/f ...

  10. PyQt(Python+Qt)学习随笔:QTabWidget选项卡部件的documentMode属性作用

    老猿Python博文目录 专栏:使用PyQt开发图形界面Python应用 老猿Python博客地址 QTabWidget的documentMode属性用于控制是否以适合文档页的模式呈现选项卡部件.这与 ...