单元测试
测试需要保证独立性,不依赖某一个方法或者数据库库中的某一条数据。
@BeforeClass:在测试类加载之前,这个方法加载执行一次
(在整个类初始化之前执行一次使用这个,和类有关,只执行一次,所以是静态的)
@AfterClass:在类销毁的时候执行一次
(在整个类执行一次使用这个,和类有关,只执行一次,所以是静态的)
@Before:调用任何测试方法之前,它修饰的方法都会调用一次。
@After:调用任何测试方法之后,它修饰的方法都会调用一次。
判断两个小数时,需要第三个参数,精度(判断到几位小数相等不相等)
@RunWith(SpringRunner.class)
@SpringBootTest
public class SpringBootTests {
private DiscussPost data;
@Autowired
private DiscussPostMapper discussPostMapper;
@BeforeClass
public static void beforeClass(){
System.out.println("beforeClass");
}
@AfterClass
public static void afterClass(){
System.out.println("afterClass");
}
@Before
public void before(){//在每个测试方法执行之前都会构造data,不依赖数据库中的数据
System.out.println("before");
data=new DiscussPost();
data.setId(111);
data.setContent("Test");
data.setScore(100.0);
discussPostMapper.insertDiscussPost(data);
}
@After
public void after(){//在每个测试方法执行之后,删除测试数据(状态改为2)
System.out.println("after");
discussPostMapper.updateDiscussStatus(data.getId(),2);
}
@Test
public void test1(){
System.out.println("test1");
}
@Test
public void test2(){
System.out.println("test2");
}
@Test
public void testFindDiscussPost(){
DiscussPost post = discussPostMapper.selectDiscussById(data.getId());
//用断言判断得到的结果是否正确(你期望得到的数据,真实的数据)
Assert.assertNotNull(post);
Assert.assertEquals(data.getContent(),post.getContent());
}
@Test
public void testUpdateScore(){
int row = discussPostMapper.updateDiscussScore(data.getId(), 200.00);
Assert.assertEquals(1,row);
DiscussPost post = discussPostMapper.selectDiscussById(data.getId());
Assert.assertEquals(200.00,post.getScore(),2);
}
}
项目监控
因为使用SpringBoot简化了很多配置,但是底层为我们做了很多事情,当项目上线时,我们要关注项目的运行情况。
端点:
先导包
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
默认一些端点是暴露的,一些是禁用的(关闭服务器),默认你只能访问两个端点,其他的想访问要配置。
暴露beans端点,日志,或者所有的端点都可以访问,再禁掉要关闭的
#actuator
management.endpoints.web.exposure.include=*
management.endpoints.web.exposure.exclude=info,caches
我想监控的内容和业务有关系,自定义端点
监控数据库,看当前连接是否正常。
交给Spring管理,@Endpoint给端点一个id名,以后便于访问。
调用端点时,尝试获取数据连接,看连接是否成功。通过连接池访问连接(spring容器来管理的)。
@ReadOperation:通过get请求来访问
写在try块里面的资源,自动加上finally,自动关闭。返回json字符串
@Component
@Endpoint(id = "database")//交给Spring管理,@Endpoint给端点一个id名,以后便于访问。
public class DatabaseEndpoint {
private static final Logger logger= LoggerFactory.getLogger(DatabaseEndpoint.class);
@Autowired
private DataSource dataSource;
@ReadOperation//@ReadOperation:通过get请求来访问
public String checkConnection(){
try(
Connection connection = dataSource.getConnection()
){
return CommunityUtil.getJSIONString(0,"获取链接成功");
}catch (Exception e){
logger.error("连接数据库失败:"+e.getMessage());
return CommunityUtil.getJSIONString(1,"获取连接失败");
}
}
}
对端点路径进行权限管理。在SecurityConfig里面配置一下,
项目部署
Nginx分流、
1、在服务器打包会包含所有的jar,比较大
2、本地环境和linux环境有区别,本地打好的包再上面会出现问题。
代理浏览器的就叫代理,代理服务器的叫反向代理。
Nginx、tomcat、项目关系:
浏览器发出请求,访问Nginx,Nginx再发给tomcat,tomcat默认访问root目录下的首页。
如果像访问其他目录下的,需要再访问请求路径下的目录名
但是我不想敲下级目录,输入域名后直接可以访问设定的命名文件。
步骤:
1、将tomcat自带的ROOT删了,在我们项目打包的时候,命名为ROOT.war
2、处理根路径,我们项目中没有处理根路径,我们要使/等于访问项目的/index
/重定向或者转发到/index,
3、ROOT项目没有访问名,我们之前在项目中加了访问名,要去掉。
声明项目打成war包,且定义war包名字为ROOT
还要修改配置文件中的一些路径c,d盘这种,Linux上没有,但是我们不能在原文件上修改,springboot允许存在多套配置文件。(开发、生产、部署、测试。。。)
生产环境下将缓存可以打开
在默认的配置文件里,配置那个配置生效。(开发的时候用develop,部署的时候用produce)
修改启动文件,部署到tomcat里面(本身就有main方法,一个程序不可能有两个main方法),web项目启动。
提供接口,从哪个入口进.
先将项目clean,再将其传到linux服务器下,利用linux里面的maven打包,放到tomcat的webapp下.
不要执行测试,
启动tomcat(删除webapp下的D:)
部署之后,只能看日志.
项目总结
用户管理不用session,为什么?分布式部署出现的问题。我们将信息存在了Redis里面,ThreadLocal,
控制器的通知Advice,统一处理异常。
AOP记录日志。
redis的数据结构,什么样的功能用什么样的数据。
通知Kafka队列,生产者与消费者模式(实例代码),明白什么样的功能能用他去解决。
Quart:定时任务。 Caffeine:做本地缓存
网站整体架构
客户端向服务器发请求(静态请求:css,html。动态请求:controller)。Nginx部署两台,主(处理请求 )从(备份).将静态资源放到CDN(全国都有dreqcxn)上,用户去加载静态资源时,就近加载离你最近的CDN
,速度很快。
Nginx分发请求,分给某一台服务器。服务器里面有本地缓存,服务器还会调用mysql(两台,一台读,一台写,写入的数据会同步到读的数据库,效率高)。
Redis缓存(二级缓存),
多台部署保证高性能、高可靠。
性能,安全尤为重要。
1、职业素养(数据结构、算法)
2、项目经验(掌握的技术栈)
3、钻研能力(那熟问到底,有多深)
项目中用到的设计模式:
工厂模式、单例模式、代理模式,比比皆是,讲课时都提到过的。
总结
1.核心功能:
- 发帖、评论、私信、转发;
- 点赞、关注、通知、搜索;
- 权限、统计、调度、监控;
2.核心技术:
- Spring Boot、SSM
- Redis、Kafka、ElasticSearch
- Spring Security、Quatz、Caffeine
3.项目亮点:
- 项目构建在Spring Boot+SSM框架之上,并统一的进行了状态管理、事务管理、异常处理;
- 利用Redis实现了点赞和关注功能,单机可达5000TPS;
- 利用Kafka实现了异步的站内通知,单机可达7000TPS;
- 利用ElasticSearch实现了全文搜索功能,可准确匹配搜索结果,并高亮显示关键词;
- 利用Caffeine+Redis实现了两级缓存,并优化了热门帖子的访问,单机可达8000QPS。
- 利用Spring Security实现了权限控制,实现了多重角色、URL级别的权限管理;
- 利用HyperLogLog、Bitmap分别实现了UV、DAU的统计功能,100万用户数据只需*M内存空间;
- 利用Quartz实现了任务调度功能,并实现了定时计算帖子分数、定时清理垃圾文件等功能;
单机可达5000TPS; - 利用Kafka实现了异步的站内通知,单机可达7000TPS;
- 利用ElasticSearch实现了全文搜索功能,可准确匹配搜索结果,并高亮显示关键词;
- 利用Caffeine+Redis实现了两级缓存,并优化了热门帖子的访问,单机可达8000QPS。
- 利用Spring Security实现了权限控制,实现了多重角色、URL级别的权限管理;
- 利用HyperLogLog、Bitmap分别实现了UV、DAU的统计功能,100万用户数据只需*M内存空间;
- 利用Quartz实现了任务调度功能,并实现了定时计算帖子分数、定时清理垃圾文件等功能;
- 利用Actuator对应用的Bean、缓存、日志、路径等多个维度进行了监控,并通过自定义的端点对数据库连接进行了监控。