发表于: 2018-06-09 23:44:20
2 953
今天完成的事情:(一定要写非常细致的内容,比如说学会了盒子模型,了解了Margin)
一、继续tuscany
1.因为昨天使用引用就失效,
所以直接不使用引用这次,直接使用注入的方式来操作,
public class Calculator implements ICalculator{
private ApplicationContext ctx = new ClassPathXmlApplicationContext("classpath:applicationContext.xml");
private IAdd add=ctx.getBean(IAdd.class);
// @Autowired
// private IAdd add;
// public IAdd getAdd() {
// return add;
// }
//
// @Reference
// public void setAdd(IAdd add) {
// this.add = add;
// }
//暂时只使用单组件,而不使用引用
@Override
public double add(double a, double b) {
return this.add.add(a,b);
// return a+b;
}
}
将注入需要的相关配置放进applicationContext.xml
然后启动就可以发现已经成功了。
至于为什么引用失败我就真的不知道了,其实也没多大的影响,只是合成组件的思路就暂时无法执行了,本来可以使用多个组件合成,现在只能重新去定义这个组件,就显得很蠢。不过好处就是不用写set/get方法了。
2.然后是服务端和客户端的分离
首先是在客户端实现同名接口
public interface ICalculator {
double add(double a,double b);
}
然后是在composite去定义service name,url和port
<!--组件名-->
<component name="CalculatorServiceComponent">
<!--组件对应实现类-->
<implementation.java class="com.task.tuscany.server.Calculator" />
<service name="Calculator">
<!--在客户端也需要实现此接口才行-->
<interface.java interface="com.task.tuscany.server.ICalculator"/>
<!--客户端调用的uri,暴露ip,port,serviceName-->
<tuscany:binding.rmi uri="rmi://127.0.0.1:8099/CalculatorRMIService"/>
</service>
<!--<reference name="Add" target="AddComponent"/>-->
</component>
需要注意的是,这里在服务端就把uri写死了,不像rmi在服务端只写了端口号和服务名,所以相比较会比较笨重。
然后是main方法中只开启节点,
在客户端写Main方法调用即可
ICalculator c= (ICalculator) Naming.lookup("//127.0.0.1:8099/CalculatorRMIService");
System.out.println(c.add(1, 2));
可以看到此时操作成功
3.那么现在我要在原来的基础上使用多个组件的话,就得定义多个组件。
比如我现在需要再增加一个HelloWorld的组件,就需要在composite中再多定义一个component即可
首先是常规的接口和实现类
@Remotable
public interface IHelloWorld {
String sayHello(String world);
}
public class HelloWord implements IHelloWorld {
@Override
public String sayHello(String world) {
System.out.println("Hello"+world);
return "Hello"+world;
}
}
注意看和之前的区别,这里多了一个@Remotable的标签,如果不加这个标签的话,就会报错说少了这个标签,可能这个标签加了之后程序才知道这个接口可以实现远程调用。
然后就是composite,注意看区别
<!--组件名-->
<component name="CalculatorServiceComponent">
<!--组件对应实现类-->
<implementation.java class="com.task.tuscany.server.Calculator" />
<service name="ICalculator">
<!--在客户端也需要实现此接口才行-->
<interface.java interface="com.task.tuscany.server.ICalculator"/>
<!--客户端调用的uri,暴露ip,port,serviceName-->
<tuscany:binding.rmi uri="rmi://127.0.0.1:8099/CalculatorRMIService"/>
</service>
<!--<reference name="Add" target="AddComponent"/>-->
</component>
<!--二号组件-->
<component name="HelloWorldServiceComponent">
<implementation.java class="com.task.tuscany.server.HelloWord" />
<service name="IHelloWorld">
<!--在客户端也需要实现此接口才行-->
<interface.java interface="com.task.tuscany.server.IHelloWorld"/>
<!--客户端调用的uri,暴露ip,port,serviceName-->
<tuscany:binding.rmi uri="rmi://127.0.0.1:8099/HelloWorldRMIService"/>
</service>
</component>
可以看到,我之前 的service name是对应的实现类的名字,但是这里必须得使用接口名,这就是加了@Remoteable标签的区别,不加的话需要对应实现类的名字,加了需要对应接口的名字。
同理,在客户端增加相对应的接口,然后就可以在main方法中调用了
public static void main(String[] args) throws Exception{
ICalculator c= (ICalculator) Naming.lookup("//127.0.0.1:8099/CalculatorRMIService");
System.out.println(c.add(1, 2));
IHelloWorld h=(IHelloWorld)Naming.lookup("//127.0.0.1:8099/HelloWorldRMIService");
System.out.println(h.sayHello("spring"));
}
结果如下,可以看到两个组件都调用成功了
4.按照道理,接下来我应该加到自己项目里,但是这里的spring的版本太低了,和我之前项目的jar包有冲突,所以就不进行这一步了。服务器也不放上去了,方法和rmi也差不多,其实我是怕真遇到问题百度都百度不到,很难受。
直接去学习Dubbo比较好。
二、深度思考
1.什么是微服务?
1)微服务是一种架构风格,一个大型复杂软件应用由一个或多个微服务组成。系统中的各个微服务可被独立部署,各个微服务之间是松耦合的。每个微服务仅关注于完成一件任务并很好地完成该任务。在所有情况下,每个任务代表着一个小的业务能力。
2)记录型系统(System of Record)将从微服务方法中获益最多。例如可将大型应用按相对独立的业务功能分解成若干个微服务实现。
交互型系统(System of Engagement)也将受益于微服务方法,例如渠道应用可以应用“后端服务前端”的模式实现。 分析型系统(System of Insight)则可能对微服务受益不多。其他架构模式如管道及过滤模式可能更适用于分析型系统。
3)优点
每个服务都比较简单,只关注于一个业务功能。
微服务架构方式是松耦合的,可以提供更高的灵活性。
微服务可通过最佳及最合适的不同的编程语言与工具进行开发,能够做到有的放矢地解决针对性问题。
每个微服务可由不同团队独立开发,互不影响,加快推出市场的速度。
微服务架构是持续交付(CD)的巨大推动力,允许在频繁发布不同服务的同时保持系统其他部分的可用性和稳定性。
4)缺点
运维开销及成本增加:整体应用可能只需部署至一小片应用服务区集群,而微服务架构可能变成需要构建/测试/部署/运行数十个独立的服务,并可能需要支持多种语言和环境。这导致一个整体式系统如果由20个微服务组成,可能需要40~60个进程。
必须有坚实的DevOps开发运维一体化技能:开发人员需要熟知运维与投产环境,开发人员也需要掌握必要的数据存储技术如NoSQL,具有较强DevOps技能的人员比较稀缺,会带来招聘人才方面的挑战。
隐式接口及接口匹配问题:把系统分为多个协作组件后会产生新的接口,这意味着简单的交叉变化可能需要改变许多组件,并需协调一起发布。在实际环境中,一个新品发布可能被迫同时发布大量服务,由于集成点的大量增加,微服务架构会有更高的发布风险。
代码重复:某些底层功能需要被多个服务所用,为了避免将“同步耦合引入到系统中”,有时需要向不同服务添加一些代码,这就会导致代码重复。
分布式系统的复杂性:作为一种分布式系统,微服务引入了复杂性和其他若干问题,例如网络延迟、容错性、消息序列化、不可靠的网络、异步机制、版本化、差异化的工作负载等,开发人员需要考虑以上的分布式系统问题。
异步机制:微服务往往使用异步编程、消息与并行机制,如果应用存在跨微服务的事务性处理,其实现机制会变得复杂化。
可测性的挑战:在动态环境下服务间的交互会产生非常微妙的行为,难以可视化及全面测试。经典微服务往往不太重视测试,更多的是通过监控发现生产环境的异常,进而快速回滚或采取其他必要的行动。但对于特别在意风险规避监管或投产环境错误会产生显著影响的场景下需要特别注意。
2.什么是SCA?什么是SOA?
1.SCA(Service Component Architecture)中文翻译为“服务组件架构”,是一种全新的软件架构思想。
2.SOA
Service-Oriented Architecture,面向服务的架构。
- 是一种面向通用集成服务的、松耦合的架构实现方式,是web时代服务发展的产物;
- 使用"分层"理念,比传统的"观察者"模式更高级且更有优势,主要体现在易扩展性和可灾;
- 适用于大型复杂业务系统的数据共享。
目前多数企业都在使用SOA架构模式,各个业务层只需将主要精力用于其自己的业务代码,对于核心的服务只需通过简单切明确的接口定义与服务提供方进行交互、通讯等。
三、任务总结
任务总结
1.任务名称:java-task9
2.成果链接:https://github.com/superkingdan/task9
3.任务耗时:6.7-6.9共三天,有点慢,因为资料太少了,报错了之后都找不到解决办法。然后前一天跑得好好的demoi第二天又跑不起来了,很神奇。
4.技能脑图:对tuscany的理解不是很深刻,因为一直在报错找错,找不到,换方法中,期间学习了一下多模块管理,避免像task8一样把server和client还要分开写的尴尬情况。。。
官方脑图
个人脑图
5.任务总结
1)tuscany总的来说和RMI差不多,都是远程调用实现web和service的分离,但是其相比RMI局限性更多:
第一个是jar包的版本,其spring版本是3.0.5,古董版本,如果使用,很多其他的包就用不了,比如aspects。
第二个是其服务端就必须设置url,这样子就会显得比较笨重,不如rmi那种只写端口和service name来的灵活。
2)使用时不知道是我自己操作问题还是啥,合成组件无法使用,最后只能使用依赖注入来调用,感觉和SCA介绍里吹得天花乱坠不一样啊。
3)多个服务组件一起调用时,要在接口上打上@Remotable标签,然后服务名必须写为接口名,否则会报莫名其妙的错误。
4)没有上服务器操作,但是感觉应该和RMI差不多。
明天计划的事情:(一定要写非常细致的内容)
学习Dubbo,今天看了师兄的小课堂是讲Dubbo,感觉还比较简单,而且实现起来功能也比RMI丰富,明天尝试一下。
遇到的问题:(遇到什么困难,怎么解决的)
@Remotable的问题,不过参考师兄日报解决了
收获:(通过今天的学习,学到了什么知识)
1.完成了tuscany的分离
2.实现了多组件调用
3.稍微了解了一下Dubbo
评论